diff options
-rw-r--r-- | shlibs/blkid/src/partitions/partitions.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c index 060461d27..76cb21d40 100644 --- a/shlibs/blkid/src/partitions/partitions.c +++ b/shlibs/blkid/src/partitions/partitions.c @@ -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]; |