summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorINSUN PYO <insun.pyo@samsung.com>2020-11-19 10:49:04 +0900
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-12-08 18:08:31 +0100
commit00d4c414284e1316a77251f17202adda1f61f171 (patch)
treebfabbb9a976055d8741c18687e69126e0f1ce11c
parent02b25eaa92261a3988438ae8baacae9eff4e4172 (diff)
downloadsystemd-00d4c414284e1316a77251f17202adda1f61f171.tar.gz
sd-device-enumerator: do not return error when a device is removed
If /sys/class/OOO node is created and destroyed during booting (kernle driver initialization fails), systemd-udev-trigger.service fails due to race condition. ***** race condition *********************************************************************************** 1. kernel driver create /sys/class/OOO 2. systemd-udev-trigger.service execues "/usr/bin/udevadm trigger --type=devices --action=add" 3. device_enumerator_scan_devices() => enumerator_scan_devices_all() => enumerator_scan_dir("class") => opendir("/sys/class") and iterate all subdirs ==> enumerator_scan_dir_and_add_devices("/sys/class/OOO") 4. kernel driver fails and destroy /sys/class/OOO 5. enumerator_scan_dir_and_add_devices("/sys/class/OOO") fails in opendir("/sys/class/OOO") 6. "systemd-udev-trigger.service" fails 7. udev coldplug fails and some device units not ready 8. mount units asociated with device units fail 9. local-fs.target fails 10. enters emergency mode ******************************************************************************************************** ***** status of systemd-udev-trigger.service unit ****************************************************** $ systemctl status systemd-udev-trigger.service systemd-udev-trigger.service - udev Coldplug all Devices Loaded: loaded (/usr/lib/systemd/system/systemd-udev-trigger.service; static; vendor preset: enabled) Active: failed (Result: exit-code) since Thu 2020-01-02 13:16:54 KST; 22min ago Docs: man:udev(7) man:systemd-udevd.service(8) Process: 2162 ExecStart=/usr/bin/udevadm trigger --type=subsystems --action=add (code=exited, status=0/SUCCESS) Process: 2554 ExecStart=/usr/bin/udevadm trigger --type=devices --action=add (code=exited, status=1/FAILURE) Main PID: 2554 (code=exited, status=1/FAILURE) Jan 02 13:16:54 localhost udevadm[2554]: Failed to scan devices: No such file or directory Jan 02 13:16:54 localhost systemd[1]: systemd-udev-trigger.service: Main process exited, code=exited, status=1/FAILURE Jan 02 13:16:54 localhost systemd[1]: systemd-udev-trigger.service: Failed with result 'exit-code'. Jan 02 13:16:54 localhost systemd[1]: Failed to start udev Coldplug all Devices. ******************************************************************************************************* ***** journal log with Environment=SYSTEMD_LOG_LEVEL=debug in systemd-udev-trigger.service *********** Jan 01 21:57:20 localhost udevadm[2039]: sd-device-enumerator: Scanning /sys/bus Jan 01 21:57:20 localhost udevadm[2522]: sd-device-enumerator: Scan all dirs Jan 01 21:57:20 localhost udevadm[2522]: sd-device-enumerator: Scanning /sys/bus Jan 01 21:57:21 localhost udevadm[2522]: sd-device-enumerator: Scanning /sys/class Jan 01 21:57:21 localhost udevadm[2522]: sd-device-enumerator: Failed to scan /sys/class: No such file or directory Jan 01 21:57:21 localhost udevadm[2522]: Failed to scan devices: No such file or directory ******************************************************************************************************* (cherry picked from commit cfb6197bc31eb6b2631dec7bf8d7a253e7891016)
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index d0e9d590af..d03433ee79 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -425,7 +425,8 @@ static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator,
dir = opendir(path);
if (!dir)
- return -errno;
+ /* this is necessarily racey, so ignore missing directories */
+ return (errno == ENOENT && (subdir1 || subdir2)) ? 0 : -errno;
FOREACH_DIRENT_ALL(dent, dir, return -errno) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;