[Libguestfs] [p2v PATCH] disks.c: skip SCSI floppy drives with no disk inserted

Laszlo Ersek lersek at redhat.com
Wed Nov 9 13:52:22 UTC 2022


A SCSI floppy drive with no disk inserted looks like a normal /dev/sd*
node, but causes the nbdkit file plugin to fail with ENOMEDIUM. Filter out
such devices altogether -- unlike CD-ROMs (for which we create a device
model in the target, albeit with no medium inserted), empty floppies
should not be converted in any way.

https://bugzilla.redhat.com/show_bug.cgi?id=2140997
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---

Notes:
    This patch still needs testing; the ISO image is at
    <http://lacos.interhost.hu/exclude-floppies-rhbz-2140997/b19895a5acd1/livecd-p2v-202211091434.iso>,
    sha256 sum:
    b0666a9140b03e12829982179bf7da2ac5477737fb53760d2e8c527d8a2bf55a.

 disks.c | 58 ++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/disks.c b/disks.c
index 4eb006246d84..aafe467f9e9a 100644
--- a/disks.c
+++ b/disks.c
@@ -20,6 +20,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <error.h>
+#include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -67,6 +68,57 @@ partition_parent (dev_t part_dev)
   return makedev (parent_major, parent_minor);
 }
 
+/**
+ * Return true if the named device (eg. C<dev == "sda">) is a Removable Media
+ * SCSI Disk with no media inserted. This covers floppy drives, but not CD-ROM
+ * drives (intentionally).
+ */
+static int
+device_has_no_media (const char *dev)
+{
+  int ret;
+  gchar *sysfs_pathname;
+  gchar *sysfs_contents;
+  gsize sysfs_size;
+  gchar *dev_pathname;
+  int dev_fd;
+
+  ret = 0;
+
+  if (!STRPREFIX (dev, "sd"))
+    return ret;
+
+  sysfs_pathname = g_strdup_printf ("/sys/block/%s/removable", dev);
+
+  if (!g_file_get_contents (sysfs_pathname, &sysfs_contents, &sysfs_size, NULL))
+    goto free_sysfs_pathname;
+
+  if (sysfs_size < 2 || sysfs_contents[0] != '1' || sysfs_contents[1] != '\n')
+    goto free_sysfs_contents;
+
+  dev_pathname = g_strdup_printf ("/dev/%s", dev);
+
+  dev_fd = open (dev_pathname, O_RDONLY | O_CLOEXEC);
+  if (dev_fd == -1) {
+    if (errno == ENOMEDIUM)
+      ret = 1;
+
+    goto free_dev_pathname;
+  }
+  close (dev_fd);
+
+free_dev_pathname:
+  g_free (dev_pathname);
+
+free_sysfs_contents:
+  g_free (sysfs_contents);
+
+free_sysfs_pathname:
+  g_free (sysfs_pathname);
+
+  return ret;
+}
+
 /**
  * Return true if the named device (eg. C<dev == "sda">) contains the
  * root filesystem.  C<root_device> is the major:minor of the root
@@ -139,6 +191,12 @@ find_all_disks (char ***disks, char ***removable)
         STRPREFIX (d->d_name, "ubd") ||
         STRPREFIX (d->d_name, "vd")) {
       char *p;
+      /* Skip SCSI disk drives with removable media that have no media inserted
+       * -- effectively, empty floppy drives. Note that SCSI CD-ROMs are named
+       * C<sr*> and thus handled on the other branch.
+       */
+      if (device_has_no_media (d->d_name))
+        continue;
 
       /* Skip the device containing the root filesystem. */
       if (device_contains (d->d_name, root_device))


More information about the Libguestfs mailing list