]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: improve whole-disk detection when read /proc/partitions
authorKarel Zak <kzak@redhat.com>
Tue, 8 Jan 2019 11:07:18 +0000 (12:07 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 8 Jan 2019 11:07:18 +0000 (12:07 +0100)
blkid(8) in high-level mode checks partitions and unpartitioned
whole-disk devices from the file /proc/partitions.

The current heuristic assumes that partition name ends with a digit.
Unfortunately, this is not correct -- for example md0 or nvme0n1 are
whole-disk devices.

This commit uses sysfs_devno_is_wholedisk() to make sure the device is
a partition (according to kernel or DM). It's probably more expensive,
because this way requires more syscalls (to read stuff from /sys etc.).

The patch also adds more information to the blkid(8) man page.

Addresses: https://github.com/karelzak/util-linux/issues/728
Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/devname.c
misc-utils/blkid.8

index 986bcf2418d6a02d9f80a0411a9d92aff4747dc7..129a349aca7660fe8cfc83eb1087c8d46b966629 100644 (file)
@@ -452,6 +452,7 @@ static int probe_all(blkid_cache cache, int only_if_new)
        char ptname0[128 + 1], ptname1[128 + 1], *ptname = NULL;
        char *ptnames[2];
        dev_t devs[2];
+       int iswhole[2] = { 0, 0 };
        int ma, mi;
        unsigned long long sz;
        int lens[2] = { 0, 0 };
@@ -489,7 +490,7 @@ static int probe_all(blkid_cache cache, int only_if_new)
                        continue;
                devs[which] = makedev(ma, mi);
 
-               DBG(DEVNAME, ul_debug("read partition name %s", ptname));
+               DBG(DEVNAME, ul_debug("read device name %s", ptname));
 
                /* Skip whole disk devs unless they have no partitions.
                 * If base name of device has changed, also
@@ -499,15 +500,14 @@ static int probe_all(blkid_cache cache, int only_if_new)
                 *
                 * Skip extended partitions.
                 * heuristic: size is 1
-                *
-                * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
                 */
 
                lens[which] = strlen(ptname);
+               iswhole[which] = sysfs_devno_is_wholedisk(devs[which]);
 
-               /* ends in a digit, clearly a partition, so check */
-               if (isdigit(ptname[lens[which] - 1])) {
-                       DBG(DEVNAME, ul_debug("partition dev %s, devno 0x%04X",
+               /* probably partition, so check */
+               if (!iswhole[which]) {
+                       DBG(DEVNAME, ul_debug(" partition dev %s, devno 0x%04X",
                                   ptname, (unsigned int) devs[which]));
 
                        if (sz > 1)
@@ -521,7 +521,9 @@ static int probe_all(blkid_cache cache, int only_if_new)
                 * on it, remove the whole-disk dev from the cache if
                 * it exists.
                 */
-               if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) {
+               if (lens[last] && iswhole[last]
+                   && !strncmp(ptnames[last], ptname, lens[last])) {
+
                        list_for_each_safe(p, pnext, &cache->bic_devs) {
                                blkid_dev tmp;
 
@@ -529,14 +531,14 @@ static int probe_all(blkid_cache cache, int only_if_new)
                                tmp = list_entry(p, struct blkid_struct_dev,
                                                 bid_devs);
                                if (tmp->bid_devno == devs[last]) {
-                                       DBG(DEVNAME, ul_debug("freeing %s",
+                                       DBG(DEVNAME, ul_debug(" freeing %s",
                                                       tmp->bid_name));
                                        blkid_free_dev(tmp);
                                        cache->bic_flags |= BLKID_BIC_FL_CHANGED;
                                        break;
                                }
                        }
-                       lens[last] = 0;
+                       lens[last] = 0;         /* mark as checked */
                }
                /*
                 * If last was not checked because it looked like a whole-disk
@@ -544,11 +546,12 @@ static int probe_all(blkid_cache cache, int only_if_new)
                 * check last as well.
                 */
                if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) {
-                       DBG(DEVNAME, ul_debug("whole dev %s, devno 0x%04X",
+                       DBG(DEVNAME, ul_debug(" whole dev %s, devno 0x%04X",
                                   ptnames[last], (unsigned int) devs[last]));
                        probe_one(cache, ptnames[last], devs[last], 0,
                                  only_if_new, 0);
-                       lens[last] = 0;
+
+                       lens[last] = 0;         /* mark as checked */
                }
        }
 
index d1cec1deabac15ac356047f9322f4313c77f5bca..ac36bee48a4146cf84830169d18a9a558f72ba15 100644 (file)
@@ -78,7 +78,7 @@ is specified, tokens from only this device are displayed.
 It is possible to specify multiple
 .I device
 arguments on the command line.
-If none is given, all devices which appear in
+If none is given, all partitions or unpartitioned devices which appear in
 .I /proc/partitions
 are shown, if they are recognized.
 .PP