142 lines
5.2 KiB
Diff
142 lines
5.2 KiB
Diff
From 35e49f2856dc7e80cfc6c9af3dca4e3aad9b8cb5 Mon Sep 17 00:00:00 2001
|
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
Date: Wed, 5 Jul 2023 11:44:00 +0900
|
|
Subject: [PATCH] sd-device: do not read uevent file in device_clone_with_db()
|
|
|
|
Follow-up for 381f6d4ba5551898e7ff19189485072b94879281.
|
|
|
|
When the function is called, the device may be already removed, and
|
|
another device has the same syspath. Such situation can occur when a
|
|
partition removed and another is created. In that case, the sysfs paths
|
|
of the removed and newly created partitions can be same, but their
|
|
devnums are different, and thus the database files corresponding to the
|
|
devices are also different.
|
|
|
|
Fixes #27981.
|
|
|
|
Conflict:adapt context
|
|
Reference:https://github.com/systemd/systemd/commit/35e49f2856dc7e80cfc6c9af3dca4e3aad9b8cb5
|
|
|
|
---
|
|
src/libsystemd/sd-device/device-private.c | 78 +++++++++--------------
|
|
1 file changed, 31 insertions(+), 47 deletions(-)
|
|
|
|
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
|
|
index 61f174a..d1600f6 100644
|
|
--- a/src/libsystemd/sd-device/device-private.c
|
|
+++ b/src/libsystemd/sd-device/device-private.c
|
|
@@ -747,51 +747,56 @@ int device_rename(sd_device *device, const char *name) {
|
|
return device_add_property_internal(device, "INTERFACE", name);
|
|
}
|
|
|
|
-static int device_shallow_clone(sd_device *device, sd_device **ret) {
|
|
+int device_clone_with_db(sd_device *device, sd_device **ret) {
|
|
_cleanup_(sd_device_unrefp) sd_device *dest = NULL;
|
|
- const char *val = NULL;
|
|
+ const char *key, *val;
|
|
int r;
|
|
|
|
assert(device);
|
|
assert(ret);
|
|
|
|
+ /* The device may be already removed. Let's copy minimal set of information that was obtained through
|
|
+ * netlink socket. */
|
|
+
|
|
r = device_new_aux(&dest);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
+ /* Seal device to prevent reading the uevent file, as the device may have been already removed. */
|
|
+ dest->sealed = true;
|
|
+
|
|
+ /* Copy syspath, then also devname, sysname or sysnum can be obtained. */
|
|
r = device_set_syspath(dest, device->syspath, false);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
- (void) sd_device_get_subsystem(device, &val);
|
|
- r = device_set_subsystem(dest, val);
|
|
- if (r < 0)
|
|
- return r;
|
|
- if (streq_ptr(val, "drivers")) {
|
|
- r = free_and_strdup(&dest->driver_subsystem, device->driver_subsystem);
|
|
+ /* Copy other information stored in database. Here, do not use FOREACH_DEVICE_PROPERTY() and
|
|
+ * sd_device_get_property_value(), as they calls device_properties_prepare() ->
|
|
+ * device_read_uevent_file(), but as commented in the above, the device may be already removed and
|
|
+ * reading uevent file may fail. */
|
|
+ ORDERED_HASHMAP_FOREACH_KEY(val, key, device->properties) {
|
|
+ if (streq(key, "MINOR"))
|
|
+ continue;
|
|
+
|
|
+ if (streq(key, "MAJOR")) {
|
|
+ const char *minor = NULL;
|
|
+
|
|
+ minor = ordered_hashmap_get(device->properties, "MINOR");
|
|
+ r = device_set_devnum(dest, val, minor);
|
|
+ } else
|
|
+ r = device_amend(dest, key, val);
|
|
if (r < 0)
|
|
return r;
|
|
- }
|
|
-
|
|
- /* The device may be already removed. Let's copy minimal set of information to make
|
|
- * device_get_device_id() work without uevent file. */
|
|
|
|
- if (sd_device_get_property_value(device, "IFINDEX", &val) >= 0) {
|
|
- r = device_set_ifindex(dest, val);
|
|
- if (r < 0)
|
|
- return r;
|
|
- }
|
|
-
|
|
- if (sd_device_get_property_value(device, "MAJOR", &val) >= 0) {
|
|
- const char *minor = NULL;
|
|
-
|
|
- (void) sd_device_get_property_value(device, "MINOR", &minor);
|
|
- r = device_set_devnum(dest, val, minor);
|
|
- if (r < 0)
|
|
- return r;
|
|
+ if (streq(key, "SUBSYSTEM") && streq(val, "drivers")) {
|
|
+ r = free_and_strdup(&dest->driver_subsystem, device->driver_subsystem);
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+ }
|
|
}
|
|
|
|
- r = device_read_uevent_file(dest);
|
|
+ /* Finally, read the udev database. */
|
|
+ r = device_read_db_internal(dest, /* force = */ true);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
@@ -799,27 +804,6 @@ static int device_shallow_clone(sd_device *device, sd_device **ret) {
|
|
return 0;
|
|
}
|
|
|
|
-int device_clone_with_db(sd_device *device, sd_device **ret) {
|
|
- _cleanup_(sd_device_unrefp) sd_device *dest = NULL;
|
|
- int r;
|
|
-
|
|
- assert(device);
|
|
- assert(ret);
|
|
-
|
|
- r = device_shallow_clone(device, &dest);
|
|
- if (r < 0)
|
|
- return r;
|
|
-
|
|
- r = device_read_db(dest);
|
|
- if (r < 0)
|
|
- return r;
|
|
-
|
|
- dest->sealed = true;
|
|
-
|
|
- *ret = TAKE_PTR(dest);
|
|
- return 0;
|
|
-}
|
|
-
|
|
int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
|
|
_cleanup_(sd_device_unrefp) sd_device *ret = NULL;
|
|
int r;
|
|
--
|
|
2.39.1
|
|
|