Skip to content

Commit 2082cf9

Browse files
author
Laszlo Ersek
committed
disks.c: skip SCSI floppy drives with no disk inserted
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 <[email protected]> Message-Id: <[email protected]> Acked-by: Richard W.M. Jones <[email protected]>
1 parent a1cee38 commit 2082cf9

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

disks.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <dirent.h>
2121
#include <errno.h>
2222
#include <error.h>
23+
#include <fcntl.h>
2324
#include <inttypes.h>
2425
#include <stdio.h>
2526
#include <stdlib.h>
@@ -67,6 +68,57 @@ partition_parent (dev_t part_dev)
6768
return makedev (parent_major, parent_minor);
6869
}
6970

71+
/**
72+
* Return true if the named device (eg. C<dev == "sda">) is a Removable Media
73+
* SCSI Disk with no media inserted. This covers floppy drives, but not CD-ROM
74+
* drives (intentionally).
75+
*/
76+
static int
77+
device_has_no_media (const char *dev)
78+
{
79+
int ret;
80+
gchar *sysfs_pathname;
81+
gchar *sysfs_contents;
82+
gsize sysfs_size;
83+
gchar *dev_pathname;
84+
int dev_fd;
85+
86+
ret = 0;
87+
88+
if (!STRPREFIX (dev, "sd"))
89+
return ret;
90+
91+
sysfs_pathname = g_strdup_printf ("/sys/block/%s/removable", dev);
92+
93+
if (!g_file_get_contents (sysfs_pathname, &sysfs_contents, &sysfs_size, NULL))
94+
goto free_sysfs_pathname;
95+
96+
if (sysfs_size < 2 || sysfs_contents[0] != '1' || sysfs_contents[1] != '\n')
97+
goto free_sysfs_contents;
98+
99+
dev_pathname = g_strdup_printf ("/dev/%s", dev);
100+
101+
dev_fd = open (dev_pathname, O_RDONLY | O_CLOEXEC);
102+
if (dev_fd == -1) {
103+
if (errno == ENOMEDIUM)
104+
ret = 1;
105+
106+
goto free_dev_pathname;
107+
}
108+
close (dev_fd);
109+
110+
free_dev_pathname:
111+
g_free (dev_pathname);
112+
113+
free_sysfs_contents:
114+
g_free (sysfs_contents);
115+
116+
free_sysfs_pathname:
117+
g_free (sysfs_pathname);
118+
119+
return ret;
120+
}
121+
70122
/**
71123
* Return true if the named device (eg. C<dev == "sda">) contains the
72124
* root filesystem. C<root_device> is the major:minor of the root
@@ -139,6 +191,12 @@ find_all_disks (char ***disks, char ***removable)
139191
STRPREFIX (d->d_name, "ubd") ||
140192
STRPREFIX (d->d_name, "vd")) {
141193
char *p;
194+
/* Skip SCSI disk drives with removable media that have no media inserted
195+
* -- effectively, empty floppy drives. Note that SCSI CD-ROMs are named
196+
* C<sr*> and thus handled on the other branch.
197+
*/
198+
if (device_has_no_media (d->d_name))
199+
continue;
142200

143201
/* Skip the device containing the root filesystem. */
144202
if (device_contains (d->d_name, root_device))

0 commit comments

Comments
 (0)