]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
eject: use sysfs API to detect hotplug
authorKarel Zak <kzak@redhat.com>
Tue, 2 Dec 2014 10:00:19 +0000 (11:00 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 2 Dec 2014 10:00:19 +0000 (11:00 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/eject.c

index 0dfd30166673de1b7dead58e03e9dfb263dfda42..a816b208f433e4f7e16b780f71606708af9c7667 100644 (file)
  */
 #define TRAY_WAS_ALREADY_OPEN_USECS  200000    /* about 0.2 seconds */
 
-/* eject(1) is able to eject only 'removable' devices (attribute in /sys)
- * _or_ devices connected by hotplug subsystem.
- */
-static const char * const hotplug_subsystems[] = {
-       "usb",
-       "ieee1394",
-       "pcmcia",
-       "mmc",
-       "ccw"
-};
-
 struct eject_control {
        struct libmnt_table *mtab;
        char *device;                   /* device or mount point to be ejected */
@@ -820,111 +809,18 @@ done:
        return count;
 }
 
-static int is_hotpluggable_subsystem(const char *name)
-{
-       size_t i;
-
-       for (i = 0; i < ARRAY_SIZE(hotplug_subsystems); i++)
-               if (strcmp(name, hotplug_subsystems[i]) == 0)
-                       return 1;
-
-       return 0;
-}
-
-#define SUBSYSTEM_LINKNAME     "/subsystem"
-
-/*
- * For example:
- *
- * chain: /sys/dev/block/../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/ \
- *                           1-1.2:1.0/host65/target65:0:0/65:0:0:0/block/sdb
- *
- * The function check if <chain>/subsystem symlink exists, if yes then returns
- * basename of the readlink result, and remove the last subdirectory from the
- * <chain> path.
- */
-static char *get_subsystem(char *chain, char *buf, size_t bufsz)
-{
-       size_t len;
-       char *p;
-
-       if (!chain || !*chain)
-               return NULL;
-
-       len = strlen(chain);
-       if (len + sizeof(SUBSYSTEM_LINKNAME) > PATH_MAX)
-               return NULL;
-
-       do {
-               ssize_t sz;
-
-               /* append "/subsystem" to the path */
-               memcpy(chain + len, SUBSYSTEM_LINKNAME, sizeof(SUBSYSTEM_LINKNAME));
-
-               /* try if subsystem symlink exists */
-               sz = readlink(chain, buf, bufsz - 1);
-
-               /* remove last subsystem from chain */
-               chain[len] = '\0';
-               p = strrchr(chain, '/');
-               if (p) {
-                       *p = '\0';
-                       len = p - chain;
-               }
-
-               if (sz > 0) {
-                       /* we found symlink to subsystem, return basename */
-                       buf[sz] = '\0';
-                       return basename(buf);
-               }
-
-       } while (p);
-
-       return NULL;
-}
-
 static int is_hotpluggable(const struct eject_control *ctl)
 {
        struct sysfs_cxt cxt = UL_SYSFSCXT_EMPTY;
-       char devchain[PATH_MAX];
-       char subbuf[PATH_MAX];
        dev_t devno;
        int rc = 0;
-       ssize_t sz;
-       char *sub;
 
        devno = sysfs_devname_to_devno(ctl->device, NULL);
        if (sysfs_init(&cxt, devno, NULL) != 0)
                return 0;
 
-       /* check /sys/dev/block/<maj>:<min>/removable attribute */
-       if (sysfs_read_int(&cxt, "removable", &rc) == 0 && rc == 1) {
-               verbose(ctl, _("%s: is removable device"), ctl->device);
-               goto done;
-       }
-
-       /* read /sys/dev/block/<maj>:<min> symlink */
-       sz = sysfs_readlink(&cxt, NULL, devchain, sizeof(devchain));
-       if (sz <= 0 || sz + sizeof(_PATH_SYS_DEVBLOCK "/") > sizeof(devchain))
-               goto done;
-
-       devchain[sz++] = '\0';
-
-       /* create absolute patch from the link */
-       memmove(devchain + sizeof(_PATH_SYS_DEVBLOCK "/") - 1, devchain, sz);
-       memcpy(devchain, _PATH_SYS_DEVBLOCK "/",
-              sizeof(_PATH_SYS_DEVBLOCK "/") - 1);
+       rc = sysfs_is_hotpluggable(&cxt);
 
-       while ((sub = get_subsystem(devchain, subbuf, sizeof(subbuf)))) {
-               rc = is_hotpluggable_subsystem(sub);
-               if (rc) {
-                       verbose(ctl, _("%s: connected by hotplug subsystem: %s"),
-                               ctl->device, sub);
-                       break;
-               }
-       }
-
-done:
        sysfs_deinit(&cxt);
        return rc;
 }