And make it also check the existence of the udev database.
return 0;
}
- r = sd_device_get_is_initialized(device);
+ r = device_is_processed(device);
if (r < 0)
- return log_link_warning_errno(link, r, "Could not determine whether the device is initialized: %m");
+ return log_link_warning_errno(link, r, "Could not determine whether the device is processed by udevd: %m");
if (r == 0) {
/* not yet ready */
log_link_debug(link, "link pending udev initialization...");
return 0;
}
- r = device_is_processing(device);
- if (r < 0)
- return log_link_warning_errno(link, r, "Failed to determine whether the device is being processed: %m");
- if (r > 0) {
- log_link_debug(link, "Interface is being processed by udevd, pending initialization.");
- return 0;
- }
-
return link_initialized(link, device);
}
return r;
}
-int device_is_processing(sd_device *dev) {
+int device_is_processed(sd_device *dev) {
int r;
assert(dev);
+ /* sd_device_get_is_initialized() only checks if the udev database file exists. However, even if the
+ * database file exist, systemd-udevd may be still processing the device, e.g. when the udev rules
+ * for the device have RUN tokens. See issue #30056. Hence, to check if the device is really
+ * processed by systemd-udevd, we also need to read ID_PROCESSING property. */
+
+ r = sd_device_get_is_initialized(dev);
+ if (r <= 0)
+ return r;
+
r = device_get_property_bool(dev, "ID_PROCESSING");
if (r == -ENOENT)
- return false; /* defaults to false */
+ return true; /* If the property does not exist, then it means that the device is processed. */
+ if (r < 0)
+ return r;
- return r;
+ return !r;
}
bool device_for_action(sd_device *dev, sd_device_action_t a) {
int device_wait_for_initialization(sd_device *device, const char *subsystem, usec_t timeout_usec, sd_device **ret);
int device_wait_for_devlink(const char *path, const char *subsystem, usec_t timeout_usec, sd_device **ret);
int device_is_renaming(sd_device *dev);
-int device_is_processing(sd_device *dev);
+int device_is_processed(sd_device *dev);
bool device_for_action(sd_device *dev, sd_device_action_t action);