diff options
author | Karel Zak | 2014-12-02 11:00:19 +0100 |
---|---|---|
committer | Karel Zak | 2014-12-02 11:00:19 +0100 |
commit | bc265f7cfa1018df129336bd79bb6817d335be5f (patch) | |
tree | c3c373a5d79ed454d2e2e1b6df2944652df97ed3 /sys-utils | |
parent | lib/sysfs: add subsystem and hotplug detection (diff) | |
download | kernel-qcow2-util-linux-bc265f7cfa1018df129336bd79bb6817d335be5f.tar.gz kernel-qcow2-util-linux-bc265f7cfa1018df129336bd79bb6817d335be5f.tar.xz kernel-qcow2-util-linux-bc265f7cfa1018df129336bd79bb6817d335be5f.zip |
eject: use sysfs API to detect hotplug
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils')
-rw-r--r-- | sys-utils/eject.c | 106 |
1 files changed, 1 insertions, 105 deletions
diff --git a/sys-utils/eject.c b/sys-utils/eject.c index 0dfd30166..a816b208f 100644 --- a/sys-utils/eject.c +++ b/sys-utils/eject.c @@ -71,17 +71,6 @@ */ #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; } |