Simplify device path scan and avoid stat();
authorMilan Broz <gmazyland@gmail.com>
Wed, 18 May 2011 17:25:21 +0000 (17:25 +0000)
committerMilan Broz <gmazyland@gmail.com>
Wed, 18 May 2011 17:25:21 +0000 (17:25 +0000)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@526 36d66b0a-2a48-0410-832c-cd162a569da5

ChangeLog
lib/libdevmapper.c

index 072fee6..2aafddf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2011-05-17  Milan Broz  <mbroz@redhat.com>
        * Fix keyfile=- processing in create command (1.3.0).
+       * Simplify device path status check.
 
 2011-05-03  Milan Broz  <mbroz@redhat.com>
        * Do not ignore size argument for create command (1.2.0).
index e3472c5..8e58860 100644 (file)
@@ -259,7 +259,7 @@ static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_le
        return result;
 }
 
-static char *lookup_dev(const char *dev_id)
+static char *lookup_dev_old(const char *dev_id)
 {
        uint32_t major, minor;
        dev_t dev;
@@ -290,6 +290,66 @@ static char *lookup_dev(const char *dev_id)
        return result;
 }
 
+/* Return path to DM device */
+static char *dm_device_path(const char *dev_id)
+{
+       int major, minor;
+       struct dm_task *dmt;
+       const char *name;
+       char path[PATH_MAX];
+
+       if (sscanf(dev_id, "%d:%d", &major, &minor) != 2)
+               return NULL;
+
+       if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
+               return NULL;
+       if (!dm_task_set_minor(dmt, minor) ||
+           !dm_task_set_major(dmt, major) ||
+           !dm_task_run(dmt) ||
+           !(name = dm_task_get_name(dmt))) {
+               dm_task_destroy(dmt);
+               return NULL;
+       }
+
+       if (snprintf(path, sizeof(path), "/dev/mapper/%s", name) < 0)
+               path[0] = '\0';
+
+       dm_task_destroy(dmt);
+
+       return strdup(path);
+}
+
+static char *lookup_dev(const char *dev_id)
+{
+       char link[PATH_MAX], path[PATH_MAX], *devname;
+       struct stat st;
+       ssize_t len;
+
+       if (snprintf(path, sizeof(path), "/sys/dev/block/%s", dev_id) < 0)
+               return NULL;
+
+       len = readlink(path, link, sizeof(link));
+       if (len < 0) {
+               if (stat("/sys/dev/block", &st) < 0)
+                       return lookup_dev_old(dev_id);
+               return NULL;
+       }
+
+       link[len] = '\0';
+       devname = strrchr(link, '/');
+       if (!devname)
+               return NULL;
+       devname++;
+
+       if (!strncmp(devname, "dm-", 3))
+               return dm_device_path(dev_id);
+
+       if (snprintf(path, sizeof(path), "/dev/%s", devname) < 0)
+               return NULL;
+
+       return strdup(path);
+}
+
 static int _dev_read_ahead(const char *dev, uint32_t *read_ahead)
 {
        int fd, r = 0;