X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibelogind%2Fsd-device%2Fsd-device.c;h=97da4a8eea0d33a981439ed82f450e5377680b0c;hb=9b3a72550211800eaf34348a76898ed37f931d27;hp=0dd0e14eef929283b67345cb201e0c3b5b72f23b;hpb=f48dd74a8d39b6074f820f904953f5cece03b9b0;p=elogind.git diff --git a/src/libelogind/sd-device/sd-device.c b/src/libelogind/sd-device/sd-device.c index 0dd0e14ee..97da4a8ee 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; @@ -499,7 +509,13 @@ int device_read_uevent_file(sd_device *device) { path = strjoina(syspath, "/uevent"); r = read_full_file(path, &uevent, &uevent_len); - if (r < 0) { + 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; } @@ -556,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; } @@ -624,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; @@ -697,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) { @@ -769,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; + return log_debug_errno(r, "sd-device: could not set subsystem for %s: %m", device->devpath); device->subsystem_set = true; } @@ -1179,12 +1193,12 @@ int device_get_id_filename(sd_device *device, const char **ret) { 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 @@ -1197,7 +1211,7 @@ int device_get_id_filename(sd_device *device, const char **ret) { r = asprintf(&id, "+%s:%s", subsystem, sysname); if (r < 0) - return -errno; + return -ENOMEM; } device->id_filename = id; @@ -1209,7 +1223,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; @@ -1226,9 +1240,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; @@ -1297,11 +1313,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; @@ -1781,8 +1799,8 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, value_len = strlen(_value); /* drop trailing newlines */ - while (value_len > 0 && _value[--value_len] == '\n') - _value[value_len] = '\0'; + while (value_len > 0 && _value[value_len - 1] == '\n') + _value[--value_len] = '\0'; /* value length is limited to 4k */ if (value_len > 4096)