summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-device/device-private.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-device/device-private.c')
-rw-r--r--src/libsystemd/sd-device/device-private.c302
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);
-}