You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
7.9 KiB
197 lines
7.9 KiB
7 months ago
|
From 73dbfdaab1d633e3a1ae96cc15c551eaa2fd4243 Mon Sep 17 00:00:00 2001
|
||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||
|
Date: Fri, 28 Oct 2022 10:21:57 +0900
|
||
|
Subject: [PATCH] udevadm-trigger: settle with synthetic UUID if the kernel
|
||
|
support it
|
||
|
|
||
|
If the kernel support synthetic UUID in uevent, then let's assume that
|
||
|
the UUID is unique, and check only if the received UUID matches we
|
||
|
specified.
|
||
|
|
||
|
Partially fixes #25115.
|
||
|
|
||
|
(cherry picked from commit dfbd824a0b780310d7f865a6ea0d60434d924683)
|
||
|
|
||
|
Related: RHEL-5988
|
||
|
---
|
||
|
src/udev/udevadm-trigger.c | 82 +++++++++++++++++++-------------------
|
||
|
1 file changed, 40 insertions(+), 42 deletions(-)
|
||
|
|
||
|
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
|
||
|
index cda31edd75..3909fa237c 100644
|
||
|
--- a/src/udev/udevadm-trigger.c
|
||
|
+++ b/src/udev/udevadm-trigger.c
|
||
|
@@ -11,10 +11,12 @@
|
||
|
#include "device-util.h"
|
||
|
#include "fd-util.h"
|
||
|
#include "fileio.h"
|
||
|
+#include "id128-util.h"
|
||
|
#include "parse-util.h"
|
||
|
#include "path-util.h"
|
||
|
#include "process-util.h"
|
||
|
#include "set.h"
|
||
|
+#include "static-destruct.h"
|
||
|
#include "string-util.h"
|
||
|
#include "strv.h"
|
||
|
#include "udevadm.h"
|
||
|
@@ -31,8 +33,9 @@ static bool arg_settle = false;
|
||
|
static int exec_list(
|
||
|
sd_device_enumerator *e,
|
||
|
sd_device_action_t action,
|
||
|
- Hashmap *settle_hashmap) {
|
||
|
+ Set **ret_settle_path_or_ids) {
|
||
|
|
||
|
+ _cleanup_set_free_ Set *settle_path_or_ids = NULL;
|
||
|
int uuid_supported = -1;
|
||
|
const char *action_str;
|
||
|
sd_device *d;
|
||
|
@@ -119,60 +122,62 @@ static int exec_list(
|
||
|
printf(SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
|
||
|
|
||
|
if (arg_settle) {
|
||
|
- _cleanup_free_ sd_id128_t *mid = NULL;
|
||
|
- _cleanup_free_ char *sp = NULL;
|
||
|
+ if (uuid_supported) {
|
||
|
+ sd_id128_t *dup;
|
||
|
|
||
|
- sp = strdup(syspath);
|
||
|
- if (!sp)
|
||
|
- return log_oom();
|
||
|
+ dup = newdup(sd_id128_t, &id, 1);
|
||
|
+ if (!dup)
|
||
|
+ return log_oom();
|
||
|
|
||
|
- mid = newdup(sd_id128_t, &id, 1);
|
||
|
- if (!d)
|
||
|
- return log_oom();
|
||
|
+ r = set_ensure_consume(&settle_path_or_ids, &id128_hash_ops_free, dup);
|
||
|
+ } else {
|
||
|
+ char *dup;
|
||
|
+
|
||
|
+ dup = strdup(syspath);
|
||
|
+ if (!dup)
|
||
|
+ return log_oom();
|
||
|
|
||
|
- r = hashmap_put(settle_hashmap, sp, mid);
|
||
|
+ r = set_ensure_consume(&settle_path_or_ids, &path_hash_ops_free, dup);
|
||
|
+ }
|
||
|
if (r < 0)
|
||
|
return log_oom();
|
||
|
-
|
||
|
- TAKE_PTR(sp);
|
||
|
- TAKE_PTR(mid);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ if (ret_settle_path_or_ids)
|
||
|
+ *ret_settle_path_or_ids = TAKE_PTR(settle_path_or_ids);
|
||
|
+
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *userdata) {
|
||
|
- Hashmap *settle_hashmap = ASSERT_PTR(userdata);
|
||
|
- sd_id128_t *settle_id;
|
||
|
+ Set *settle_path_or_ids = * (Set**) ASSERT_PTR(userdata);
|
||
|
const char *syspath;
|
||
|
- char *k;
|
||
|
+ sd_id128_t id;
|
||
|
int r;
|
||
|
|
||
|
assert(dev);
|
||
|
|
||
|
r = sd_device_get_syspath(dev, &syspath);
|
||
|
if (r < 0) {
|
||
|
- log_debug_errno(r, "Failed to get syspath of device event, ignoring: %m");
|
||
|
+ log_device_debug_errno(dev, r, "Failed to get syspath of device event, ignoring: %m");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
- settle_id = hashmap_get2(settle_hashmap, syspath, (void**) &k);
|
||
|
- if (!settle_id) {
|
||
|
- log_debug("Got uevent for unexpected device '%s', ignoring.", syspath);
|
||
|
- return 0;
|
||
|
- }
|
||
|
- if (!sd_id128_is_null(*settle_id)) { /* If this is SD_ID128_NULL then we are on pre-4.13 and have no UUID to check, hence don't */
|
||
|
- sd_id128_t event_id;
|
||
|
+ if (sd_device_get_trigger_uuid(dev, &id) >= 0) {
|
||
|
+ _cleanup_free_ sd_id128_t *saved = NULL;
|
||
|
|
||
|
- r = sd_device_get_trigger_uuid(dev, &event_id);
|
||
|
- if (r < 0) {
|
||
|
- log_debug_errno(r, "Got uevent without synthetic UUID for device '%s', ignoring: %m", syspath);
|
||
|
+ saved = set_remove(settle_path_or_ids, &id);
|
||
|
+ if (!saved) {
|
||
|
+ log_device_debug(dev, "Got uevent not matching expected UUID, ignoring.");
|
||
|
return 0;
|
||
|
}
|
||
|
+ } else {
|
||
|
+ _cleanup_free_ char *saved = NULL;
|
||
|
|
||
|
- if (!sd_id128_equal(event_id, *settle_id)) {
|
||
|
- log_debug("Got uevent not matching expected UUID for device '%s', ignoring.", syspath);
|
||
|
+ saved = set_remove(settle_path_or_ids, syspath);
|
||
|
+ if (!saved) {
|
||
|
+ log_device_debug(dev, "Got uevent for unexpected device, ignoring.");
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
@@ -181,12 +186,9 @@ static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *us
|
||
|
printf("settle %s\n", syspath);
|
||
|
|
||
|
if (arg_uuid)
|
||
|
- printf("settle " SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(*settle_id));
|
||
|
+ printf("settle " SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
|
||
|
|
||
|
- free(hashmap_remove(settle_hashmap, syspath));
|
||
|
- free(k);
|
||
|
-
|
||
|
- if (hashmap_isempty(settle_hashmap))
|
||
|
+ if (set_isempty(settle_path_or_ids))
|
||
|
return sd_event_exit(sd_device_monitor_get_event(m), 0);
|
||
|
|
||
|
return 0;
|
||
|
@@ -289,7 +291,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||
|
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||
|
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
|
||
|
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||
|
- _cleanup_hashmap_free_ Hashmap *settle_hashmap = NULL;
|
||
|
+ _cleanup_set_free_ Set *settle_path_or_ids = NULL;
|
||
|
usec_t ping_timeout_usec = 5 * USEC_PER_SEC;
|
||
|
bool ping = false;
|
||
|
int c, r;
|
||
|
@@ -484,10 +486,6 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||
|
}
|
||
|
|
||
|
if (arg_settle) {
|
||
|
- settle_hashmap = hashmap_new(&path_hash_ops_free_free);
|
||
|
- if (!settle_hashmap)
|
||
|
- return log_oom();
|
||
|
-
|
||
|
r = sd_event_default(&event);
|
||
|
if (r < 0)
|
||
|
return log_error_errno(r, "Failed to get default event: %m");
|
||
|
@@ -500,7 +498,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||
|
if (r < 0)
|
||
|
return log_error_errno(r, "Failed to attach event to device monitor: %m");
|
||
|
|
||
|
- r = sd_device_monitor_start(m, device_monitor_handler, settle_hashmap);
|
||
|
+ r = sd_device_monitor_start(m, device_monitor_handler, &settle_path_or_ids);
|
||
|
if (r < 0)
|
||
|
return log_error_errno(r, "Failed to start device monitor: %m");
|
||
|
}
|
||
|
@@ -525,11 +523,11 @@ int trigger_main(int argc, char *argv[], void *userdata) {
|
||
|
assert_not_reached();
|
||
|
}
|
||
|
|
||
|
- r = exec_list(e, action, settle_hashmap);
|
||
|
+ r = exec_list(e, action, arg_settle ? &settle_path_or_ids : NULL);
|
||
|
if (r < 0)
|
||
|
return r;
|
||
|
|
||
|
- if (event && !hashmap_isempty(settle_hashmap)) {
|
||
|
+ if (!set_isempty(settle_path_or_ids)) {
|
||
|
r = sd_event_loop(event);
|
||
|
if (r < 0)
|
||
|
return log_error_errno(r, "Event loop failed: %m");
|