]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: use partno for partitions mapped by DM
authorKarel Zak <kzak@redhat.com>
Mon, 23 May 2011 10:53:18 +0000 (12:53 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 23 May 2011 10:53:18 +0000 (12:53 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/blkid/src/partitions/partitions.c

index 060461d2714a2bb7d3cb1b4571f0408856ec669a..76cb21d4085edd1fafae937de6920c2c3c79036f 100644 (file)
@@ -892,20 +892,60 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
 {
        struct sysfs_cxt sysfs;
        uint64_t start, size;
-       int i, rc;
+       int i, rc, partno = 0;
 
        if (sysfs_init(&sysfs, devno, NULL))
                return NULL;
 
-       rc = sysfs_read_u64(&sysfs, "start", &start);
-       if (!rc)
-               rc = sysfs_read_u64(&sysfs, "size", &size);
+       rc = sysfs_read_u64(&sysfs, "size", &size);
+       if (!rc) {
+               rc = sysfs_read_u64(&sysfs, "start", &start);
+               if (rc) {
+                       /* try to get partition number from DM uuid.
+                        */
+                       char *uuid = sysfs_strdup(&sysfs, "dm/uuid");
+                       char *tmp = uuid;
+                       char *prefix = uuid ? strsep(&tmp, "-") : NULL;
+
+                       if (prefix && strncasecmp(prefix, "part", 4) == 0) {
+                               char *end = NULL;
+
+                               partno = strtol(prefix + 4, &end, 10);
+                               if (prefix == end || (end && *end))
+                                       partno = 0;
+                               else
+                                       rc = 0;         /* success */
+                       }
+                       free(uuid);
+               }
+       }
 
        sysfs_deinit(&sysfs);
 
        if (rc)
                return NULL;
 
+       if (partno) {
+               /*
+                * Partition mapped by kpartx does not provide "start" offset
+                * in /sys, but if we know partno and size of the partition
+                * that we can probably make the releation bettween the device
+                * and an entry in partition table.
+                */
+                for (i = 0; i < ls->nparts; i++) {
+                        blkid_partition par = &ls->parts[i];
+
+                        if (partno != blkid_partition_get_partno(par))
+                                continue;
+
+                        if (size == blkid_partition_get_size(par) ||
+                            (blkid_partition_is_extended(par) && size <= 1024))
+                                return par;
+
+                }
+                return NULL;
+       }
+
        for (i = 0; i < ls->nparts; i++) {
                blkid_partition par = &ls->parts[i];