sd-device: make cloned sd_device object can read udev database without uevent file

Some devices sent CHANGE and REMOVE uevent simultaneously.
To support that such device read udev database, let's copy minimal set of
properties which requires to read the database.

Fixes #19788.
This commit is contained in:
Yu Watanabe
2021-06-05 18:05:26 +09:00
parent c7d6ebb13e
commit 381f6d4ba5
+31 -5
View File
@@ -751,7 +751,7 @@ int device_rename(sd_device *device, const char *name) {
int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
_cleanup_(sd_device_unrefp) sd_device *ret = NULL;
const char *subsystem;
const char *val;
int r;
assert(old_device);
@@ -765,17 +765,43 @@ int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
if (r < 0)
return r;
if (sd_device_get_subsystem(old_device, &subsystem) >= 0) {
r = device_set_subsystem(ret, subsystem);
if (sd_device_get_subsystem(old_device, &val) >= 0) {
r = device_set_subsystem(ret, val);
if (r < 0)
return r;
if (streq(val, "drivers")) {
ret->driver_subsystem = strdup(old_device->driver_subsystem);
if (!ret->driver_subsystem)
return -ENOMEM;
}
} else
ret->subsystem_set = true;
ret->devnum = old_device->devnum;
/* 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(old_device, "IFINDEX", &val) >= 0) {
r = device_set_ifindex(ret, val);
if (r < 0)
return r;
}
if (sd_device_get_property_value(old_device, "MAJOR", &val) >= 0) {
const char *minor = NULL;
(void) sd_device_get_property_value(old_device, "MINOR", &minor);
r = device_set_devnum(ret, val, minor);
if (r < 0)
return r;
}
/* And then read uevent file, but ignore errors, as some devices seem to return a spurious
* error on read, e.g. -ENODEV, and even if ifindex or devnum is set in the above,
* sd_device_get_ifindex() or sd_device_get_devnum() fails. See. #19788. */
(void) device_read_uevent_file(ret);
*new_device = TAKE_PTR(ret);
return 0;
}