From: Lennart Poettering Date: Wed, 26 May 2021 14:09:18 +0000 (+0200) Subject: sd-device: add API for triggering synthetic uevents with UUID X-Git-Tag: v249-rc1~137^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b485fd932ad37a945569857127b7e929e87e17b2;p=thirdparty%2Fsystemd.git sd-device: add API for triggering synthetic uevents with UUID Since kernel 4.13 the kerne allows passing a UUID to generated uevents. Optionally do so via a new sd_device_trigger_with_uuid() call, and add sd_device_get_trigger_uuid() as helper to retrieve the UUID from a uevent we receive. This is useful for tracking uevents through the udev system, and waiting for specific triggers. (Note that the 4.13 patch allows passing arbitrary meta-info into the uevent as well. This does not add an API for that, because I am not convinced it makes sense — as it conflicts with our general rule that events are "stateless" if you so will — and it complicates the interface quite a bit). This replaces #13881 in a way, which added a similar infra, but which stalled, and whose synchronous settling APIs are somewhat problematic and probably not material to merge. --- diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 996bf25d6c2..1606981e1e1 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -757,4 +757,6 @@ global: sd_device_monitor_filter_add_match_sysattr; sd_device_monitor_filter_add_match_parent; sd_device_get_usec_initialized; + sd_device_trigger_with_uuid; + sd_device_get_trigger_uuid; } LIBSYSTEMD_248; diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 363e4f2dd0a..a5bd7d8d84d 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -16,6 +16,7 @@ #include "fileio.h" #include "fs-util.h" #include "hashmap.h" +#include "id128-util.h" #include "macro.h" #include "parse-util.h" #include "path-util.h" @@ -1869,6 +1870,34 @@ _public_ int sd_device_get_property_value(sd_device *device, const char *key, co return 0; } +_public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) { + const char *s; + sd_id128_t id; + int r; + + assert_return(device, -EINVAL); + + /* Retrieves the UUID attached to a uevent when triggering it from userspace via + * sd_device_trigger_with_uuid() or an equivalent interface. Returns -ENOENT if the record is not + * caused by a synthetic event and -ENODATA if it was but no UUID was specified */ + + r = sd_device_get_property_value(device, "SYNTH_UUID", &s); + if (r < 0) + return r; + + if (streq(s, "0")) /* SYNTH_UUID=0 is set whenever a device is triggered by userspace without specifying a UUID */ + return -ENODATA; + + r = sd_id128_from_string(s, &id); + if (r < 0) + return r; + + if (ret) + *ret = id; + + return 0; +} + static int device_cache_sysattr_value(sd_device *device, const char *key, char *value) { _cleanup_free_ char *new_key = NULL, *old_value = NULL; int r; @@ -2096,5 +2125,41 @@ _public_ int sd_device_trigger(sd_device *device, sd_device_action_t action) { if (!s) return -EINVAL; + /* This uses the simple no-UUID interface of kernel < 4.13 */ return sd_device_set_sysattr_value(device, "uevent", s); } + +_public_ int sd_device_trigger_with_uuid( + sd_device *device, + sd_device_action_t action, + sd_id128_t *ret_uuid) { + + char buf[ID128_UUID_STRING_MAX]; + const char *s, *j; + sd_id128_t u; + int r; + + assert_return(device, -EINVAL); + + /* If noone wants to know the UUID, use the simple interface from pre-4.13 times */ + if (!ret_uuid) + return sd_device_trigger(device, action); + + s = device_action_to_string(action); + if (!s) + return -EINVAL; + + r = sd_id128_randomize(&u); + if (r < 0) + return r; + + id128_to_uuid_string(u, buf); + j = strjoina(s, " ", buf); + + r = sd_device_set_sysattr_value(device, "uevent", j); + if (r < 0) + return r; + + *ret_uuid = u; + return 0; +} diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h index 8b7b361295e..04599ea3821 100644 --- a/src/systemd/sd-device.h +++ b/src/systemd/sd-device.h @@ -24,6 +24,7 @@ #include #include "sd-event.h" +#include "sd-id128.h" #include "_sd-common.h" @@ -96,11 +97,13 @@ const char *sd_device_get_sysattr_next(sd_device *device); int sd_device_has_tag(sd_device *device, const char *tag); int sd_device_has_current_tag(sd_device *device, const char *tag); int sd_device_get_property_value(sd_device *device, const char *key, const char **value); +int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret); int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, const char **_value); int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, const char *value); int sd_device_set_sysattr_valuef(sd_device *device, const char *sysattr, const char *format, ...) _sd_printf_(3, 4); int sd_device_trigger(sd_device *device, sd_device_action_t action); +int sd_device_trigger_with_uuid(sd_device *device, sd_device_action_t action, sd_id128_t *ret_uuid); /* device enumerator */