]> git.ozlabs.org Git - petitboot/blobdiff - discover/devmapper.c
discover: Add platform-dummy
[petitboot] / discover / devmapper.c
index d3179f14e7fcc52c9eb71e487ac80250e44fbf05..f7407b77b3544c94d6fa85d86aac3d0c950ab7b5 100644 (file)
@@ -2,8 +2,13 @@
 #include <types/types.h>
 #include <log/log.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <string.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 #include "libdevmapper.h"
 #include "devmapper.h"
 #include "platform.h"
@@ -17,27 +22,91 @@ struct target {
        char            *params;
 };
 
-/* Return the number of sectors on a block device. Zero represents an error */
-static uint64_t get_block_sectors(struct discover_device *device)
+static unsigned long read_param_uint(struct discover_device *device,
+                               const char *param)
 {
-       unsigned long long sectors;
+       unsigned long value = 0;
        const char *tmp;
 
-       tmp = discover_device_get_param(device, "ID_PART_ENTRY_SIZE");
+       tmp = discover_device_get_param(device, param);
        if (!tmp) {
-               pb_debug("Could not retrieve ID_PART_ENTRY_SIZE for %s\n",
+               pb_debug("Could not retrieve parameter '%s' for %s\n",
+                        param, device->device_path);
+               errno = EINVAL;
+       } else {
+               errno = 0;
+               value = strtoul(tmp, NULL, 0);
+       }
+
+       /* Return errno and result directly */
+       return value;
+}
+
+/* Return the number of sectors on a block device. Zero represents an error */
+static uint64_t get_block_sectors(struct discover_device *device)
+{
+       unsigned long major, minor, sectors = 0;
+       char *attr, *buf = NULL;
+       struct stat sb;
+       int fd = -1;
+       ssize_t sz;
+
+       sectors = read_param_uint(device, "ID_PART_ENTRY_SIZE");
+       if (!errno)
+               return (uint64_t)sectors;
+       else
+               pb_debug("Error reading sector count for %s: %m\n",
                       device->device_path);
+
+       /* Either the udev property is missing or we failed to parse it.
+        * Instead try to directly read the size attribute out of sysfs */
+       major = read_param_uint(device, "MAJOR");
+       if (errno) {
+               pb_debug("Error reading %s major number\n", device->device_path);
+               return 0;
+       }
+       minor = read_param_uint(device, "MINOR");
+       if (errno) {
+               pb_debug("Error reading %s minor number\n", device->device_path);
                return 0;
        }
 
-       errno = 0;
-       sectors = strtoull(tmp, NULL, 0);
+       attr = talloc_asprintf(device, "/sys/dev/block/%lu:%lu/size",
+                              major, minor);
+       if (stat(attr, &sb)) {
+               pb_debug("Failed to stat %s, %m\n", attr);
+               goto out;
+       }
+
+       fd = open(attr, O_RDONLY);
+       if (fd < 0) {
+               pb_debug("Failed to open sysfs attribute for %s\n",
+                        device->device_path);
+               goto out;
+       }
+
+       buf = talloc_array(device, char, sb.st_size);
+       if (!buf) {
+               pb_debug("Failed to allocate space for attr\n");
+               goto out;
+       }
+
+       sz = read(fd, buf, sb.st_size);
+       if (sz <= 0) {
+               pb_debug("Failed to read sysfs attr: %m\n");
+               goto out;
+       }
+
+       sectors = strtoul(buf, NULL, 0);
        if (errno) {
-               pb_debug("Error reading sector count for %s: %s\n",
-                      device->device_path, strerror(errno));
+               pb_debug("Failed to read sectors from sysfs: %m\n");
                sectors = 0;
        }
 
+out:
+       close(fd);
+       talloc_free(buf);
+       talloc_free(attr);
        return (uint64_t)sectors;
 }
 
@@ -69,7 +138,7 @@ static bool snapshot_merge_complete(const char *dm_name)
 
        task = dm_task_create(DM_DEVICE_STATUS);
        if (!task) {
-               pb_log("%s: Error creating task\n", __func__);
+               pb_log_fn("Error creating task\n");
                return result;
        }
 
@@ -129,7 +198,7 @@ static int set_device_active(const char *dm_name, bool active)
                task = dm_task_create(DM_DEVICE_SUSPEND);
 
        if (!task) {
-               pb_log("%s: Could not create dm_task\n", __func__);
+               pb_log_fn("Could not create dm_task\n");
                return rc;
        }
 
@@ -163,7 +232,7 @@ static int run_create_task(const char *dm_name, const struct target *target)
        struct dm_task *task;
        uint32_t cookie;
 
-       pb_debug("%s: %lu %lu '%s' '%s'\n", __func__,
+       pb_debug("%s: %" PRIu64 " %" PRIu64 " '%s' '%s'\n", __func__,
                 target->start_sector, target->end_sector,
                 target->ttype, target->params);
 
@@ -217,11 +286,11 @@ static int create_base(struct discover_device *device)
                goto out;
        }
 
-       name = talloc_asprintf(device, "%s-base", device->device->id);
+       name = talloc_asprintf(device, "pb-%s-base", device->device->id);
        if (!name || run_create_task(name, &target))
                goto out;
 
-       device->ramdisk->base = talloc_asprintf(device, "/dev/mapper/%s-base",
+       device->ramdisk->base = talloc_asprintf(device, "/dev/mapper/pb-%s-base",
                                        device->device->id);
        if (!device->ramdisk->base) {
                pb_log("Failed to track new device /dev/mapper/%s-base\n",
@@ -257,12 +326,12 @@ static int create_origin(struct discover_device *device)
                goto out;
        }
 
-       name = talloc_asprintf(device, "%s-origin", device->device->id);
+       name = talloc_asprintf(device, "pb-%s-origin", device->device->id);
        if (!name || run_create_task(name, &target))
                goto out;
 
        device->ramdisk->origin = talloc_asprintf(device,
-                                       "/dev/mapper/%s-origin",
+                                       "/dev/mapper/pb-%s-origin",
                                        device->device->id);
        if (!device->ramdisk->origin) {
                pb_log("Failed to track new device /dev/mapper/%s-origin\n",
@@ -282,6 +351,7 @@ out:
 static int create_snapshot(struct discover_device *device)
 {
        struct target target;
+       char *name = NULL;
        int rc = -1;
 
        if (!device->ramdisk || !device->ramdisk->base ||
@@ -299,10 +369,11 @@ static int create_snapshot(struct discover_device *device)
                goto out;
        }
 
-       if (run_create_task(device->device->id, &target))
+       name = talloc_asprintf(device, "pb-%s", device->device->id);
+       if (!name || run_create_task(name, &target))
                goto out;
 
-       device->ramdisk->snapshot = talloc_asprintf(device, "/dev/mapper/%s",
+       device->ramdisk->snapshot = talloc_asprintf(device, "/dev/mapper/pb-%s",
                                                device->device->id);
        if (!device->ramdisk->snapshot) {
                pb_log("Failed to track new device /dev/mapper/%s\n",
@@ -313,6 +384,7 @@ static int create_snapshot(struct discover_device *device)
        rc = 0;
 
 out:
+       talloc_free(name);
        talloc_free(target.params);
        talloc_free(target.ttype);
        return rc;
@@ -389,7 +461,7 @@ static int destroy_device(const char *dm_name)
 
        task = dm_task_create(DM_DEVICE_REMOVE);
        if (!task) {
-               pb_log("%s: could not create dm_task\n", __func__);
+               pb_log_fn("could not create dm_task\n");
                return -1;
        }
 
@@ -471,13 +543,13 @@ static int reload_snapshot(struct discover_device *device, bool merge)
                         device->ramdisk->base);
        }
        if (!target.ttype || !target.params) {
-               pb_log("%s: failed to allocate parameters\n", __func__);
+               pb_log_fn("failed to allocate parameters\n");
                goto err1;
        }
 
        task = dm_task_create(DM_DEVICE_RELOAD);
        if (!task) {
-               pb_log("%s: Error creating task\n", __func__);
+               pb_log_fn("Error creating task\n");
                goto err1;
        }
 
@@ -488,7 +560,7 @@ static int reload_snapshot(struct discover_device *device, bool merge)
 
        if (!dm_task_add_target(task, target.start_sector, target.end_sector,
                                target.ttype, target.params)) {
-               pb_log("%s: Failed to set target\n", __func__);
+               pb_log_fn("Failed to set target\n");
                goto err2;
        }
 
@@ -509,7 +581,7 @@ err1:
 int devmapper_merge_snapshot(struct discover_device *device)
 {
        if (device->mounted) {
-               pb_log("%s: %s still mounted\n", __func__, device->device->id);
+               pb_log_fn("%s still mounted\n", device->device->id);
                return -1;
        }