From 3172836b2f9841994ed7d0daf054d4570b8dac6f Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 26 Jun 2016 22:36:46 +0200 Subject: sd-device: enumerator - do not abort enumeration if a device fails Collect the errors and return to the caller, but continue enumerating all devices. --- src/libsystemd/sd-device/device-enumerator.c | 34 +++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index 4a7a8b1f9e..62d03ae00d 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -696,17 +696,19 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) { const char *tag; Iterator i; - int r; + int r = 0; assert(enumerator); SET_FOREACH(tag, enumerator->match_tag, i) { - r = enumerator_scan_devices_tag(enumerator, tag); - if (r < 0) - return r; + int k; + + k = enumerator_scan_devices_tag(enumerator, tag); + if (k < 0) + r = k; } - return 0; + return r; } static int parent_add_child(sd_device_enumerator *enumerator, const char *path) { @@ -838,7 +840,7 @@ static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) { int device_enumerator_scan_devices(sd_device_enumerator *enumerator) { sd_device *device; - int r; + int r = 0, k; assert(enumerator); @@ -850,22 +852,22 @@ int device_enumerator_scan_devices(sd_device_enumerator *enumerator) { sd_device_unref(device); if (!set_isempty(enumerator->match_tag)) { - r = enumerator_scan_devices_tags(enumerator); - if (r < 0) - return r; + k = enumerator_scan_devices_tags(enumerator); + if (k < 0) + r = k; } else if (enumerator->match_parent) { - r = enumerator_scan_devices_children(enumerator); - if (r < 0) - return r; + k = enumerator_scan_devices_children(enumerator); + if (k < 0) + r = k; } else { - r = enumerator_scan_devices_all(enumerator); - if (r < 0) - return r; + k = enumerator_scan_devices_all(enumerator); + if (k < 0) + r = k; } enumerator->scan_uptodate = true; - return 0; + return r; } _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator) { -- cgit v1.2.3-54-g00ecf From de7e983ea13f1cb76339db9037fc5115199396d0 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 26 Jun 2016 23:05:27 +0200 Subject: sd-device: device_id - set correctly for 'drivers' The 'drivers' pseudo-subsystem needs special treatment. These pseudo-devices are found under /sys/bus/drivers/, so needs the real subsystem encoded in the device_id in order to be resolved. The reader side already assumed this to be the case. --- src/libsystemd/sd-device/device-internal.h | 2 + src/libsystemd/sd-device/sd-device.c | 84 +++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h index ab222e27de..9fad388953 100644 --- a/src/libsystemd/sd-device/device-internal.h +++ b/src/libsystemd/sd-device/device-internal.h @@ -76,6 +76,8 @@ struct sd_device { char *subsystem; bool subsystem_set; /* don't reread subsystem */ + char *driver_subsystem; /* only set for the 'drivers' subsystem */ + bool driver_subsystem_set; /* don't reread subsystem */ char *driver; bool driver_set; /* don't reread driver */ diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 5c9e00ed80..c13f6fca28 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -75,6 +75,7 @@ _public_ sd_device *sd_device_unref(sd_device *device) { free(device->devtype); free(device->devname); free(device->subsystem); + free(device->driver_subsystem); free(device->driver); free(device->id_filename); free(device->properties_strv); @@ -766,21 +767,45 @@ int device_set_subsystem(sd_device *device, const char *_subsystem) { return 0; } +static int device_set_drivers_subsystem(sd_device *device, const char *_subsystem) { + _cleanup_free_ char *subsystem = NULL; + int r; + + assert(device); + assert(_subsystem); + assert(*_subsystem); + + subsystem = strdup(_subsystem); + if (!subsystem) + return -ENOMEM; + + r = device_set_subsystem(device, "drivers"); + if (r < 0) + return r; + + free(device->driver_subsystem); + device->driver_subsystem = subsystem; + subsystem = NULL; + + return 0; +} + _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) { + const char *syspath, *drivers = NULL; + int r; + assert_return(ret, -EINVAL); assert_return(device, -EINVAL); + r = sd_device_get_syspath(device, &syspath); + if (r < 0) + return r; + if (!device->subsystem_set) { _cleanup_free_ char *subsystem = NULL; - const char *syspath; char *path; - int r; /* read 'subsystem' link */ - r = sd_device_get_syspath(device, &syspath); - if (r < 0) - return r; - path = strjoina(syspath, "/subsystem"); r = readlink_value(path, &subsystem); if (r >= 0) @@ -788,16 +813,39 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) { /* use implicit names */ else if (path_startswith(device->devpath, "/module/")) r = device_set_subsystem(device, "module"); - else if (strstr(device->devpath, "/drivers/")) - r = device_set_subsystem(device, "drivers"); - else if (path_startswith(device->devpath, "/subsystem/") || - path_startswith(device->devpath, "/class/") || - path_startswith(device->devpath, "/bus/")) + else if (!(drivers = strstr(syspath, "/drivers/")) && + (path_startswith(device->devpath, "/subsystem/") || + path_startswith(device->devpath, "/class/") || + path_startswith(device->devpath, "/bus/"))) r = device_set_subsystem(device, "subsystem"); if (r < 0 && r != -ENOENT) return log_debug_errno(r, "sd-device: could not set subsystem for %s: %m", device->devpath); device->subsystem_set = true; + } else if (!device->driver_subsystem_set) + drivers = strstr(syspath, "/drivers/"); + + if (!device->driver_subsystem_set) { + if (drivers) { + _cleanup_free_ char *subpath = NULL; + + subpath = strndup(syspath, drivers - syspath); + if (!subpath) + r = -ENOMEM; + else { + const char *subsys; + + subsys = strrchr(subpath, '/'); + if (!subsys) + r = -EINVAL; + else + r = device_set_drivers_subsystem(device, subsys + 1); + } + if (r < 0 && r != -ENOENT) + return log_debug_errno(r, "sd-device: could not set subsystem for driver %s: %m", device->devpath); + } + + device->driver_subsystem_set = true; } if (!device->subsystem) @@ -1234,9 +1282,17 @@ int device_get_id_filename(sd_device *device, const char **ret) { if (!subsystem) return -EINVAL; - r = asprintf(&id, "+%s:%s", subsystem, sysname); - if (r < 0) - return -ENOMEM; + if (streq(subsystem, "drivers")) { + /* the 'drivers' pseudo-subsystem is special, and needs the real subsystem + * encoded as well */ + r = asprintf(&id, "+drivers:%s:%s", device->driver_subsystem, sysname); + if (r < 0) + return -ENOMEM; + } else { + r = asprintf(&id, "+%s:%s", subsystem, sysname); + if (r < 0) + return -ENOMEM; + } } device->id_filename = id; -- cgit v1.2.3-54-g00ecf From 21d6220fe0bf24fda7df9833961e022cafa439bc Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 27 Jun 2016 09:58:59 +0200 Subject: sd-device: new_from_subsystem_sysnam - support a real subsystem called 'drivers' We support writing out tags and db files in case a real subsystem called 'drivers' exists, so there is no reason to refuse parsing it. --- src/libsystemd/sd-device/sd-device.c | 43 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index c13f6fca28..d503232505 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -259,7 +259,8 @@ _public_ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum) } _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname) { - char *syspath; + char *name, *syspath; + size_t len = 0; assert_return(ret, -EINVAL); assert_return(subsystem, -EINVAL); @@ -298,33 +299,29 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s syspath = strjoina("/sys/bus/", subsys, "/drivers/", driver); if (access(syspath, F_OK) >= 0) return sd_device_new_from_syspath(ret, syspath); - } else - return -EINVAL; - } else { - char *name; - size_t len = 0; + } + } - /* translate sysname back to sysfs filename */ - name = strdupa(sysname); - while (name[len] != '\0') { - if (name[len] == '/') - name[len] = '!'; + /* translate sysname back to sysfs filename */ + name = strdupa(sysname); + while (name[len] != '\0') { + if (name[len] == '/') + name[len] = '!'; - len++; - } + len++; + } - syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", name); - if (access(syspath, F_OK) >= 0) - return sd_device_new_from_syspath(ret, syspath); + syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", name); + if (access(syspath, F_OK) >= 0) + return sd_device_new_from_syspath(ret, syspath); - syspath = strjoina("/sys/bus/", subsystem, "/devices/", name); - if (access(syspath, F_OK) >= 0) - return sd_device_new_from_syspath(ret, syspath); + syspath = strjoina("/sys/bus/", subsystem, "/devices/", name); + if (access(syspath, F_OK) >= 0) + return sd_device_new_from_syspath(ret, syspath); - syspath = strjoina("/sys/class/", subsystem, "/", name); - if (access(syspath, F_OK) >= 0) - return sd_device_new_from_syspath(ret, syspath); - } + syspath = strjoina("/sys/class/", subsystem, "/", name); + if (access(syspath, F_OK) >= 0) + return sd_device_new_from_syspath(ret, syspath); return -ENODEV; } -- cgit v1.2.3-54-g00ecf