diff options
Diffstat (limited to 'src/libsystemd/sd-device/device-private.c')
-rw-r--r-- | src/libsystemd/sd-device/device-private.c | 302 |
1 files changed, 81 insertions, 221 deletions
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index d1f1b085ac..01a5aa3d3f 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -24,6 +24,7 @@ #include "string-util.h" #include "strv.h" #include "strxcpyx.h" +#include "tmpfile-util.h" #include "user-util.h" #include "util.h" @@ -46,81 +47,6 @@ int device_add_property(sd_device *device, const char *key, const char *value) { return 0; } -static int device_add_property_internal_from_string(sd_device *device, const char *str) { - _cleanup_free_ char *key = NULL; - char *value; - - assert(device); - assert(str); - - key = strdup(str); - if (!key) - return -ENOMEM; - - value = strchr(key, '='); - if (!value) - return -EINVAL; - - *value = '\0'; - - if (isempty(++value)) - value = NULL; - - return device_add_property_internal(device, key, value); -} - -static int handle_db_line(sd_device *device, char key, const char *value) { - char *path; - int r; - - assert(device); - assert(value); - - switch (key) { - case 'S': - path = strjoina("/dev/", value); - r = device_add_devlink(device, path); - if (r < 0) - return r; - - break; - case 'L': - r = safe_atoi(value, &device->devlink_priority); - if (r < 0) - return r; - - break; - case 'E': - r = device_add_property_internal_from_string(device, value); - if (r < 0) - return r; - - break; - case 'G': - r = device_add_tag(device, value); - if (r < 0) - return r; - - break; - case 'W': - r = safe_atoi(value, &device->watch_handle); - if (r < 0) - return r; - - break; - case 'I': - r = device_set_usec_initialized(device, value); - if (r < 0) - return r; - - break; - default: - log_debug("device db: unknown key '%c'", key); - } - - return 0; -} - void device_set_devlink_priority(sd_device *device, int priority) { assert(device); @@ -134,119 +60,16 @@ void device_set_is_initialized(sd_device *device) { } int device_ensure_usec_initialized(sd_device *device, sd_device *device_old) { - char num[DECIMAL_STR_MAX(usec_t)]; - usec_t usec_initialized; - int r; + usec_t when; assert(device); if (device_old && device_old->usec_initialized > 0) - usec_initialized = device_old->usec_initialized; + when = device_old->usec_initialized; else - usec_initialized = now(CLOCK_MONOTONIC); - - r = snprintf(num, sizeof(num), USEC_FMT, usec_initialized); - if (r < 0) - return -errno; - - r = device_set_usec_initialized(device, num); - if (r < 0) - return r; + when = now(CLOCK_MONOTONIC); - return 0; -} - -static int device_read_db(sd_device *device) { - _cleanup_free_ char *db = NULL; - char *path; - const char *id, *value; - char key; - size_t db_len; - unsigned i; - int r; - - enum { - PRE_KEY, - KEY, - PRE_VALUE, - VALUE, - INVALID_LINE, - } state = PRE_KEY; - - assert(device); - - if (device->db_loaded || device->sealed) - return 0; - - r = device_get_id_filename(device, &id); - if (r < 0) - return r; - - path = strjoina("/run/udev/data/", id); - - r = read_full_file(path, &db, &db_len); - if (r < 0) { - if (r == -ENOENT) - return 0; - else - return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path); - } - - /* devices with a database entry are initialized */ - device_set_is_initialized(device); - - for (i = 0; i < db_len; i++) { - switch (state) { - case PRE_KEY: - if (!strchr(NEWLINE, db[i])) { - key = db[i]; - - state = KEY; - } - - break; - case KEY: - if (db[i] != ':') { - log_debug("sd-device: ignoring invalid db entry with key '%c'", key); - - state = INVALID_LINE; - } else { - db[i] = '\0'; - - state = PRE_VALUE; - } - - break; - case PRE_VALUE: - value = &db[i]; - - state = VALUE; - - break; - case INVALID_LINE: - if (strchr(NEWLINE, db[i])) - state = PRE_KEY; - - break; - case VALUE: - if (strchr(NEWLINE, db[i])) { - db[i] = '\0'; - r = handle_db_line(device, key, value); - if (r < 0) - log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value); - - state = PRE_KEY; - } - - break; - default: - assert_not_reached("invalid state when parsing db"); - } - } - - device->db_loaded = true; - - return 0; + return device_set_usec_initialized(device, when); } uint64_t device_get_properties_generation(sd_device *device) { @@ -271,13 +94,16 @@ int device_get_devnode_mode(sd_device *device, mode_t *mode) { int r; assert(device); - assert(mode); r = device_read_db(device); if (r < 0) return r; - *mode = device->devmode; + if (device->devmode == (mode_t) -1) + return -ENOENT; + + if (mode) + *mode = device->devmode; return 0; } @@ -286,13 +112,16 @@ int device_get_devnode_uid(sd_device *device, uid_t *uid) { int r; assert(device); - assert(uid); r = device_read_db(device); if (r < 0) return r; - *uid = device->devuid; + if (device->devuid == (uid_t) -1) + return -ENOENT; + + if (uid) + *uid = device->devuid; return 0; } @@ -321,13 +150,16 @@ int device_get_devnode_gid(sd_device *device, gid_t *gid) { int r; assert(device); - assert(gid); r = device_read_db(device); if (r < 0) return r; - *gid = device->devgid; + if (device->devgid == (gid_t) -1) + return -ENOENT; + + if (gid) + *gid = device->devgid; return 0; } @@ -367,43 +199,49 @@ static int device_amend(sd_device *device, const char *key, const char *value) { /* the caller must verify or trust this data (e.g., if it comes from the kernel) */ r = device_set_syspath(device, path, false); if (r < 0) - return log_debug_errno(r, "sd-device: could not set syspath to '%s': %m", path); + return log_device_debug_errno(device, r, "sd-device: Failed to set syspath to '%s': %m", path); } else if (streq(key, "SUBSYSTEM")) { r = device_set_subsystem(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set subsystem to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set subsystem to '%s': %m", value); } else if (streq(key, "DEVTYPE")) { r = device_set_devtype(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devtype to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set devtype to '%s': %m", value); } else if (streq(key, "DEVNAME")) { r = device_set_devname(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devname to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set devname to '%s': %m", value); } else if (streq(key, "USEC_INITIALIZED")) { - r = device_set_usec_initialized(device, value); + usec_t t; + + r = safe_atou64(value, &t); if (r < 0) - return log_debug_errno(r, "sd-device: could not set usec-initialized to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to parse timestamp '%s': %m", value); + + r = device_set_usec_initialized(device, t); + if (r < 0) + return log_device_debug_errno(device, r, "sd-device: Failed to set usec-initialized to '%s': %m", value); } else if (streq(key, "DRIVER")) { r = device_set_driver(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set driver to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set driver to '%s': %m", value); } else if (streq(key, "IFINDEX")) { r = device_set_ifindex(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set ifindex to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set ifindex to '%s': %m", value); } else if (streq(key, "DEVMODE")) { r = device_set_devmode(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devmode to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set devmode to '%s': %m", value); } else if (streq(key, "DEVUID")) { r = device_set_devuid(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devuid to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set devuid to '%s': %m", value); } else if (streq(key, "DEVGID")) { r = device_set_devgid(device, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devgid to '%s': %m", value); + return log_device_debug_errno(device, r, "sd-device: Failed to set devgid to '%s': %m", value); } else if (streq(key, "DEVLINKS")) { const char *word, *state; size_t l; @@ -416,7 +254,7 @@ static int device_amend(sd_device *device, const char *key, const char *value) { r = device_add_devlink(device, devlink); if (r < 0) - return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlink); + return log_device_debug_errno(device, r, "sd-device: Failed to add devlink '%s': %m", devlink); } } else if (streq(key, "TAGS")) { const char *word, *state; @@ -425,17 +263,17 @@ static int device_amend(sd_device *device, const char *key, const char *value) { FOREACH_WORD_SEPARATOR(word, l, value, ":", state) { char tag[l + 1]; - (void)strncpy(tag, word, l); + (void) strncpy(tag, word, l); tag[l] = '\0'; r = device_add_tag(device, tag); if (r < 0) - return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tag); + return log_device_debug_errno(device, r, "sd-device: Failed to add tag '%s': %m", tag); } } else { r = device_add_property_internal(device, key, value); if (r < 0) - return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value); + return log_device_debug_errno(device, r, "sd-device: Failed to add property '%s=%s': %m", key, value); } return 0; @@ -471,7 +309,7 @@ static int device_append(sd_device *device, char *key, const char **_major, cons value = strchr(key, '='); if (!value) { - log_debug("sd-device: not a key-value pair: '%s'", key); + log_device_debug(device, "sd-device: Not a key-value pair: '%s'", key); return -EINVAL; } @@ -488,6 +326,15 @@ static int device_append(sd_device *device, char *key, const char **_major, cons action = device_action_from_string(value); if (action == _DEVICE_ACTION_INVALID) return -EINVAL; + /* FIXME: remove once we no longer flush previuos state for each action */ + if (action == DEVICE_ACTION_BIND || action == DEVICE_ACTION_UNBIND) { + static bool warned; + if (!warned) { + log_device_debug(device, "sd-device: ignoring actions 'bind' and 'unbind'"); + warned = true; + } + return -EINVAL; + } } else if (streq(key, "SEQNUM")) { r = safe_atou64(value, &seqnum); if (r < 0) @@ -527,7 +374,7 @@ static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum assert(device); if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) { - log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum"); + log_device_debug(device, "sd-device: Device created from strv or nulstr lacks devpath, subsystem, action or seqnum."); return -EINVAL; } @@ -541,7 +388,7 @@ int device_new_from_strv(sd_device **ret, char **strv) { char **key; const char *major = NULL, *minor = NULL; DeviceAction action = _DEVICE_ACTION_INVALID; - uint64_t seqnum; + uint64_t seqnum = 0; int r; assert(ret); @@ -560,7 +407,7 @@ int device_new_from_strv(sd_device **ret, char **strv) { if (major) { r = device_set_devnum(device, major, minor); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor); + return log_device_debug_errno(device, r, "sd-device: Failed to set devnum %s:%s: %m", major, minor); } r = device_verify(device, action, seqnum); @@ -576,7 +423,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; const char *major = NULL, *minor = NULL; DeviceAction action = _DEVICE_ACTION_INVALID; - uint64_t seqnum; + uint64_t seqnum = 0; unsigned i = 0; int r; @@ -595,7 +442,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) { key = (char*)&nulstr[i]; end = memchr(key, '\0', len - i); if (!end) { - log_debug("sd-device: failed to parse nulstr"); + log_device_debug(device, "sd-device: Failed to parse nulstr"); return -EINVAL; } i += end - key + 1; @@ -608,7 +455,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) { if (major) { r = device_set_devnum(device, major, minor); if (r < 0) - return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor); + return log_device_debug_errno(device, r, "sd-device: Failed to set devnum %s:%s: %m", major, minor); } r = device_verify(device, action, seqnum); @@ -717,13 +564,16 @@ int device_get_watch_handle(sd_device *device, int *handle) { int r; assert(device); - assert(handle); r = device_read_db(device); if (r < 0) return r; - *handle = device->watch_handle; + if (device->watch_handle < 0) + return -ENOENT; + + if (handle) + *handle = device->watch_handle; return 0; } @@ -843,6 +693,22 @@ int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, return 0; } +int device_new_from_stat_rdev(sd_device **ret, const struct stat *st) { + char type; + + assert(ret); + assert(st); + + if (S_ISBLK(st->st_mode)) + type = 'b'; + else if (S_ISCHR(st->st_mode)) + type = 'c'; + else + return -ENOTTY; + + return sd_device_new_from_devnum(ret, type, st->st_rdev); +} + int device_copy_properties(sd_device *device_dst, sd_device *device_src) { const char *property, *value; int r; @@ -1055,8 +921,8 @@ int device_update_db(sd_device *device) { goto fail; } - log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty", - path, device->devpath); + log_device_debug(device, "sd-device: Created %s file '%s' for '%s'", has_info ? "db" : "empty", + path, device->devpath); return 0; @@ -1064,7 +930,7 @@ fail: (void) unlink(path); (void) unlink(path_tmp); - return log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath); + return log_device_debug_errno(device, r, "sd-device: Failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath); } int device_delete_db(sd_device *device) { @@ -1086,9 +952,3 @@ int device_delete_db(sd_device *device) { return 0; } - -int device_read_db_force(sd_device *device) { - assert(device); - - return device_read_db_aux(device, true); -} |