|
20 | 20 | #include <dirent.h>
|
21 | 21 | #include <errno.h>
|
22 | 22 | #include <error.h>
|
| 23 | +#include <fcntl.h> |
23 | 24 | #include <inttypes.h>
|
24 | 25 | #include <stdio.h>
|
25 | 26 | #include <stdlib.h>
|
@@ -67,6 +68,57 @@ partition_parent (dev_t part_dev)
|
67 | 68 | return makedev (parent_major, parent_minor);
|
68 | 69 | }
|
69 | 70 |
|
| 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 | + |
70 | 122 | /**
|
71 | 123 | * Return true if the named device (eg. C<dev == "sda">) contains the
|
72 | 124 | * root filesystem. C<root_device> is the major:minor of the root
|
@@ -139,6 +191,12 @@ find_all_disks (char ***disks, char ***removable)
|
139 | 191 | STRPREFIX (d->d_name, "ubd") ||
|
140 | 192 | STRPREFIX (d->d_name, "vd")) {
|
141 | 193 | 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; |
142 | 200 |
|
143 | 201 | /* Skip the device containing the root filesystem. */
|
144 | 202 | if (device_contains (d->d_name, root_device))
|
|
0 commit comments