fdisk: backport disk check from util-linux
authorLauri Kasanen <curaga@operamail.com>
Sat, 30 Apr 2011 19:31:05 +0000 (21:31 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 30 Apr 2011 19:31:05 +0000 (21:31 +0200)
With the digit check devices like mmcblk0 were skipped,
but now with 0 allowed we're seeing a ton of loop devices listed
(loop0, loop10, loop20...) as well as ramzswap0,
all which should not be shown in fdisk -l.

function                                             old     new   delta
list_devs_in_proc_partititons                        157     238     +81

Signed-off-by: Lauri Kasanen <curaga@operamail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
util-linux/fdisk.c

index da03e683eddcff7a54192177a6d5772ad81ec509..f4fd4d31dca1d5b0da6de8ddc1a5019663efd2d7 100644 (file)
@@ -2846,13 +2846,37 @@ open_list_and_close(const char *device, int user_specified)
        close_dev_fd();
 }
 
+/* Is it a whole disk? The digit check is still useful
+   for Xen devices for example. */
+static int is_whole_disk(const char *disk)
+{
+       unsigned len;
+       int fd = open(disk, O_RDONLY);
+
+       if (fd != -1) {
+               struct hd_geometry geometry;
+               int err = ioctl(fd, HDIO_GETGEO, &geometry);
+               close(fd);
+               if (!err)
+                       return (geometry.start == 0);
+       }
+
+       /* Treat "nameN" as a partition name, not whole disk */
+       /* note: mmcblk0 should work from the geometry check above */
+       len = strlen(disk);
+       if (len != 0 && isdigit(disk[len - 1]))
+               return 0;
+
+       return 1;
+}
+
 /* for fdisk -l: try all things in /proc/partitions
    that look like a partition name (do not end in a digit) */
 static void
 list_devs_in_proc_partititons(void)
 {
        FILE *procpt;
-       char line[100], ptname[100], devname[120], *s;
+       char line[100], ptname[100], devname[120];
        int ma, mi, sz;
 
        procpt = fopen_or_warn("/proc/partitions", "r");
@@ -2861,13 +2885,10 @@ list_devs_in_proc_partititons(void)
                if (sscanf(line, " %u %u %u %[^\n ]",
                                &ma, &mi, &sz, ptname) != 4)
                        continue;
-               for (s = ptname; *s; s++)
-                       continue;
-               /* note: excluding '0': e.g. mmcblk0 is not a partition name! */
-               if (s[-1] >= '1' && s[-1] <= '9')
-                       continue;
+
                sprintf(devname, "/dev/%s", ptname);
-               open_list_and_close(devname, 0);
+               if (is_whole_disk(devname))
+                       open_list_and_close(devname, 0);
        }
 #if ENABLE_FEATURE_CLEAN_UP
        fclose(procpt);