mirror of
https://github.com/systemd/systemd.git
synced 2025-03-13 00:58:27 +03:00
sd-device: use sd_device_get_sysattr_value() to read uevent file
This also replaces the custom parser with strv_split_newlines_full(). No functional change, just refactoring.
This commit is contained in:
parent
6ebbdcc0dd
commit
17dc9ec4b6
@ -787,89 +787,52 @@ static int handle_uevent_line(
|
||||
}
|
||||
|
||||
int device_read_uevent_file(sd_device *device) {
|
||||
_cleanup_free_ char *uevent = NULL;
|
||||
const char *syspath, *key = NULL, *value = NULL, *major = NULL, *minor = NULL;
|
||||
char *path;
|
||||
size_t uevent_len;
|
||||
int r;
|
||||
|
||||
enum {
|
||||
PRE_KEY,
|
||||
KEY,
|
||||
PRE_VALUE,
|
||||
VALUE,
|
||||
INVALID_LINE,
|
||||
} state = PRE_KEY;
|
||||
|
||||
assert(device);
|
||||
|
||||
if (device->uevent_loaded || device->sealed)
|
||||
return 0;
|
||||
|
||||
r = sd_device_get_syspath(device, &syspath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
device->uevent_loaded = true;
|
||||
|
||||
path = strjoina(syspath, "/uevent");
|
||||
|
||||
r = read_full_virtual_file(path, &uevent, &uevent_len);
|
||||
if (r == -EACCES || ERRNO_IS_NEG_DEVICE_ABSENT(r))
|
||||
const char *uevent;
|
||||
r = sd_device_get_sysattr_value(device, "uevent", &uevent);
|
||||
if (ERRNO_IS_NEG_PRIVILEGE(r) || ERRNO_IS_NEG_DEVICE_ABSENT(r))
|
||||
/* The uevent files may be write-only, the device may be already removed, or the device
|
||||
* may not have the uevent file. */
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(device, r, "sd-device: Failed to read uevent file '%s': %m", path);
|
||||
return log_device_debug_errno(device, r, "sd-device: Failed to read uevent file: %m");
|
||||
|
||||
for (size_t i = 0; i < uevent_len; i++)
|
||||
switch (state) {
|
||||
case PRE_KEY:
|
||||
if (!strchr(NEWLINE, uevent[i])) {
|
||||
key = &uevent[i];
|
||||
_cleanup_strv_free_ char **v = NULL;
|
||||
r = strv_split_newlines_full(&v, uevent, EXTRACT_RETAIN_ESCAPE);
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(device, r, "sd-device: Failed to parse uevent file: %m");
|
||||
|
||||
state = KEY;
|
||||
}
|
||||
|
||||
break;
|
||||
case KEY:
|
||||
if (uevent[i] == '=') {
|
||||
uevent[i] = '\0';
|
||||
|
||||
state = PRE_VALUE;
|
||||
} else if (strchr(NEWLINE, uevent[i])) {
|
||||
uevent[i] = '\0';
|
||||
log_device_debug(device, "sd-device: Invalid uevent line '%s', ignoring", key);
|
||||
|
||||
state = PRE_KEY;
|
||||
}
|
||||
|
||||
break;
|
||||
case PRE_VALUE:
|
||||
value = &uevent[i];
|
||||
state = VALUE;
|
||||
|
||||
_fallthrough_; /* to handle empty property */
|
||||
case VALUE:
|
||||
if (strchr(NEWLINE, uevent[i])) {
|
||||
uevent[i] = '\0';
|
||||
|
||||
r = handle_uevent_line(device, key, value, &major, &minor);
|
||||
if (r < 0)
|
||||
log_device_debug_errno(device, r, "sd-device: Failed to handle uevent entry '%s=%s', ignoring: %m", key, value);
|
||||
|
||||
state = PRE_KEY;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
assert_not_reached();
|
||||
const char *major = NULL, *minor = NULL;
|
||||
STRV_FOREACH(s, v) {
|
||||
char *eq = strchr(*s, '=');
|
||||
if (!eq) {
|
||||
log_device_debug(device, "sd-device: Invalid uevent line, ignoring: %s", *s);
|
||||
continue;
|
||||
}
|
||||
|
||||
*eq = '\0';
|
||||
|
||||
r = handle_uevent_line(device, *s, eq + 1, &major, &minor);
|
||||
if (r < 0)
|
||||
log_device_debug_errno(device, r,
|
||||
"sd-device: Failed to handle uevent entry '%s=%s', ignoring: %m",
|
||||
*s, eq + 1);
|
||||
}
|
||||
|
||||
if (major) {
|
||||
r = device_set_devnum(device, major, minor);
|
||||
if (r < 0)
|
||||
log_device_debug_errno(device, r, "sd-device: Failed to set 'MAJOR=%s' or 'MINOR=%s' from '%s', ignoring: %m", major, strna(minor), path);
|
||||
log_device_debug_errno(device, r,
|
||||
"sd-device: Failed to set 'MAJOR=%s' and/or 'MINOR=%s' from uevent, ignoring: %m",
|
||||
major, strna(minor));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user