X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibelogind%2Fsd-device%2Fsd-device.c;h=ddb7b93ae70bfefe2b99a665c2170da7dff2ae85;hp=7d52e3cc1d0f052f3d92de3fd9d0af7bae57363a;hb=165d7d44bd29a34a0bc598314884e3204d8f753d;hpb=6888be2d3963c5a1b03619a8ae315d7d42b1b98c diff --git a/src/libelogind/sd-device/sd-device.c b/src/libelogind/sd-device/sd-device.c index 7d52e3cc1..ddb7b93ae 100644 --- a/src/libelogind/sd-device/sd-device.c +++ b/src/libelogind/sd-device/sd-device.c @@ -158,15 +158,21 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { if (verify) { r = readlink_and_canonicalize(_syspath, &syspath); - if (r == -EINVAL) { + if (r == -ENOENT) + /* the device does not exist (any more?) */ + return -ENODEV; + else if (r == -EINVAL) { /* not a symlink */ syspath = canonicalize_file_name(_syspath); if (!syspath) { + if (errno == ENOENT) + /* the device does not exist (any more?) */ + return -ENODEV; + log_debug("sd-device: could not canonicalize '%s': %m", _syspath); return -errno; } - /* ignore errors due to the link not being a symlink */ - } else if (r < 0 && r != -EINVAL) { + } else if (r < 0) { log_debug("sd-device: could not get target of '%s': %s", _syspath, strerror(-r)); return r; } @@ -178,15 +184,17 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { path = strjoina(syspath, "/uevent"); r = access(path, F_OK); if (r < 0) { + if (errno == ENOENT) + /* this is not a valid device */ + return -ENODEV; + log_debug("sd-device: %s does not have an uevent file: %m", syspath); return -errno; } } else { /* everything else just just needs to be a directory */ - if (!is_dir(syspath, false)) { - log_debug("sd-device: %s is not a directory", syspath); - return -EINVAL; - } + if (!is_dir(syspath, false)) + return -ENODEV; } } else { syspath = strdup(_syspath); @@ -301,7 +309,7 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s return sd_device_new_from_syspath(ret, syspath); } - return -ENOENT; + return -ENODEV; } int device_set_devtype(sd_device *device, const char *_devtype) { @@ -492,6 +500,8 @@ int device_read_uevent_file(sd_device *device) { if (device->uevent_loaded || device->sealed) return 0; + device->uevent_loaded = true; + r = sd_device_get_syspath(device, &syspath); if (r < 0) return r; @@ -502,6 +512,9 @@ int device_read_uevent_file(sd_device *device) { if (r == -EACCES) /* empty uevent files may be write-only */ return 0; + else if (r == -ENOENT) + /* some devices may not have uevent files, see set_syspath() */ + return 0; else if (r < 0) { log_debug("sd-device: failed to read uevent file '%s': %s", path, strerror(-r)); return r; @@ -559,8 +572,6 @@ int device_read_uevent_file(sd_device *device) { log_debug("sd-device: could not set 'MAJOR=%s' or 'MINOR=%s' from '%s': %s", major, minor, path, strerror(-r)); } - device->uevent_loaded = true; - return 0; } @@ -627,7 +638,7 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) { if (r < 0) return r; - /* this si racey, so we might end up with the wrong device */ + /* this is racey, so we might end up with the wrong device */ if (ifr.ifr_ifindex != ifindex) return -ENODEV; @@ -700,7 +711,7 @@ static int device_new_from_child(sd_device **ret, sd_device *child) { return 0; } - return -ENOENT; + return -ENODEV; } _public_ int sd_device_get_parent(sd_device *child, sd_device **ret) { @@ -772,10 +783,10 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) { r = device_set_subsystem(device, "drivers"); else if (path_startswith(device->devpath, "/subsystem/") || path_startswith(device->devpath, "/class/") || - path_startswith(device->devpath, "/buss/")) + path_startswith(device->devpath, "/bus/")) r = device_set_subsystem(device, "subsystem"); - if (r < 0) - return r; + 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; } @@ -890,8 +901,11 @@ _public_ int sd_device_get_driver(sd_device *device, const char **ret) { if (r >= 0) { r = device_set_driver(device, driver); if (r < 0) - return r; - } + return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath); + } else if (r == -ENOENT) + device->driver_set = true; + else + return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath); } *ret = device->driver; @@ -1177,17 +1191,19 @@ int device_get_id_filename(sd_device *device, const char **ret) { return r; if (major(devnum) > 0) { + assert(subsystem); + /* use dev_t -- b259:131072, c254:0 */ r = asprintf(&id, "%c%u:%u", streq(subsystem, "block") ? 'b' : 'c', major(devnum), minor(devnum)); if (r < 0) - return -errno; + return -ENOMEM; } else if (ifindex > 0) { /* use netdev ifindex -- n3 */ r = asprintf(&id, "n%u", ifindex); if (r < 0) - return -errno; + return -ENOMEM; } else { /* use $subsys:$sysname -- pci:0000:00:1f.2 * sysname() has '!' translated, get it from devpath @@ -1198,9 +1214,12 @@ int device_get_id_filename(sd_device *device, const char **ret) { if (!sysname) return -EINVAL; + if (!subsystem) + return -EINVAL; + r = asprintf(&id, "+%s:%s", subsystem, sysname); if (r < 0) - return -errno; + return -ENOMEM; } device->id_filename = id; @@ -1212,7 +1231,7 @@ int device_get_id_filename(sd_device *device, const char **ret) { return 0; } -static int device_read_db(sd_device *device) { +int device_read_db_aux(sd_device *device, bool force) { _cleanup_free_ char *db = NULL; char *path; const char *id, *value; @@ -1229,9 +1248,11 @@ static int device_read_db(sd_device *device) { INVALID_LINE, } state = PRE_KEY; - if (device->db_loaded || device->sealed) + if (device->db_loaded || (!force && device->sealed)) return 0; + device->db_loaded = true; + r = device_get_id_filename(device, &id); if (r < 0) return r; @@ -1300,11 +1321,13 @@ static int device_read_db(sd_device *device) { } } - device->db_loaded = true; - return 0; } +static int device_read_db(sd_device *device) { + return device_read_db_aux(device, false); +} + _public_ int sd_device_get_is_initialized(sd_device *device, int *initialized) { int r;