summaryrefslogtreecommitdiffstats
path: root/misc-utils/lsblk.c
diff options
context:
space:
mode:
authorPeter Rajnoha2012-09-20 13:17:13 +0200
committerKarel Zak2012-09-21 12:25:32 +0200
commitda30cb2a87184822baf681057df4290abf568637 (patch)
tree7aa70d2e0d870856311487bf8e8364908f7a91fb /misc-utils/lsblk.c
parentlib/sysfs: fix sysfs_devname_to_devno for dm partitions (diff)
downloadkernel-qcow2-util-linux-da30cb2a87184822baf681057df4290abf568637.tar.gz
kernel-qcow2-util-linux-da30cb2a87184822baf681057df4290abf568637.tar.xz
kernel-qcow2-util-linux-da30cb2a87184822baf681057df4290abf568637.zip
lsblk: fix processing of dm partition mappings
As blkid_devno_to_wholedisk returns parent dm device for a partition mapping, the condition used in lsblk incorrectly checked the parent-child relationship. In this particular case, we need to process the dm partition mapping like any other non-partition device as dm devices always use proper holders/slaves sysfs hierarchy instead of /sys/block/<parent>/<name> that is used for real partitions. Example (test1 is a partition mapping and sdb1 is a real partition): $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 128M 0 disk `-test (dm-0) 253:0 0 128M 0 dm `-test1 (dm-1) 253:1 0 127M 0 part sdb 8:16 0 128M 0 disk `-sdb1 8:17 0 127M 0 disk Before this patch (test1 skipped!): $ lsblk -s /dev/mapper/test1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT test (dm-0) 253:0 0 128M 0 dm `-sda 8:0 0 128M 0 disk $ lsblk -s /dev/sdb1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdb1 8:17 0 127M 0 disk `-sdb 8:16 0 128M 0 disk With this patch (test1 processed correctly): $ lsblk -s /dev/mapper/test1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT test1 (dm-1) 253:1 0 127M 0 part `-test (dm-0) 253:0 0 128M 0 dm `-sda 8:0 0 128M 0 disk $ lsblk -s /dev/sdb1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdb1 8:17 0 127M 0 disk `-sdb 8:16 0 128M 0 disk
Diffstat (limited to 'misc-utils/lsblk.c')
-rw-r--r--misc-utils/lsblk.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c
index 38e1cdeba..2662460a4 100644
--- a/misc-utils/lsblk.c
+++ b/misc-utils/lsblk.c
@@ -1072,52 +1072,68 @@ static int iterate_block_devices(void)
return EXIT_SUCCESS;
}
+static char *devno_to_sysfs_name(dev_t devno, char *devname, char *buf, size_t buf_size)
+{
+ char path[PATH_MAX];
+ ssize_t len;
+
+ if (!sysfs_devno_path(devno, path, sizeof(path))) {
+ warn(_("%s: failed to compose sysfs path"), devname);
+ return NULL;
+ }
+
+ len = readlink(path, buf, buf_size);
+ if (len < 0) {
+ warn(_("%s: failed to read link"), path);
+ return NULL;
+ }
+ buf[len] = '\0';
+
+ return xstrdup(strrchr(buf, '/') + 1);
+}
+
static int process_one_device(char *devname)
{
struct blkdev_cxt parent = {}, cxt = {};
struct stat st;
- char buf[PATH_MAX + 1], *diskname = NULL;
+ char buf[PATH_MAX + 1], *name, *diskname = NULL;
dev_t disk = 0;
+ int real_part = 0;
int status = EXIT_FAILURE;
if (stat(devname, &st) || !S_ISBLK(st.st_mode)) {
warnx(_("%s: not a block device"), devname);
return EXIT_FAILURE;
}
- if (blkid_devno_to_wholedisk(st.st_rdev, buf, sizeof(buf), &disk)) {
- warn(_("%s: failed to get whole-disk device number"), devname);
+
+ if (!(name = devno_to_sysfs_name(st.st_rdev, devname, buf, PATH_MAX))) {
+ warn(_("%s: failed to get sysfs name"), devname);
return EXIT_FAILURE;
}
- if (st.st_rdev == disk) {
+
+ if (!strncmp(name, "dm-", 3)) {
+ /* dm mapping is never a real partition! */
+ real_part = 0;
+ } else {
+ if (blkid_devno_to_wholedisk(st.st_rdev, buf, sizeof(buf), &disk)) {
+ warn(_("%s: failed to get whole-disk device number"), devname);
+ return EXIT_FAILURE;
+ }
+ diskname = buf;
+ real_part = st.st_rdev != disk;
+ }
+
+ if (!real_part) {
/*
* Device is not a partition.
*/
- if (set_cxt(&cxt, NULL, NULL, buf))
+ if (set_cxt(&cxt, NULL, NULL, name))
goto leave;
process_blkdev(&cxt, NULL, !lsblk->inverse, NULL);
} else {
/*
* Partition, read sysfs name of the device.
*/
- ssize_t len;
- char path[PATH_MAX], *name;
-
- if (!sysfs_devno_path(st.st_rdev, path, sizeof(path))) {
- warn(_("failed to compose sysfs path for %s"), devname);
- goto leave;
- }
-
- diskname = xstrdup(buf);
- len = readlink(path, buf, PATH_MAX);
- if (len < 0) {
- warn(_("%s: failed to read link"), path);
- goto leave;
- }
- buf[len] = '\0';
-
- /* sysfs device name */
- name = strrchr(buf, '/') + 1;
-
if (set_cxt(&parent, NULL, NULL, diskname))
goto leave;
if (set_cxt(&cxt, &parent, &parent, name))
@@ -1131,10 +1147,10 @@ static int process_one_device(char *devname)
status = EXIT_SUCCESS;
leave:
- free(diskname);
+ free(name);
reset_blkdev_cxt(&cxt);
- if (st.st_rdev != disk)
+ if (real_part)
reset_blkdev_cxt(&parent);
return status;