diff options
author | INSUN PYO <insun.pyo@samsung.com> | 2020-11-19 10:49:04 +0900 |
---|---|---|
committer | INSUN PYO <insun.pyo@samsung.com> | 2020-11-26 10:34:06 +0900 |
commit | 16e50a3d9be8ddaf7867140fe5c21c6986976f7a (patch) | |
tree | de54c3e126fd8bf806e1faef9a894b0f736a82fc | |
parent | 16d457187c8e85eb282c779522a9ac033368568e (diff) | |
download | systemd-16e50a3d9be8ddaf7867140fe5c21c6986976f7a.tar.gz systemd-16e50a3d9be8ddaf7867140fe5c21c6986976f7a.tar.bz2 systemd-16e50a3d9be8ddaf7867140fe5c21c6986976f7a.zip |
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
*******************************************************************************************************
Change-Id: Iefc64406a72e5facf1f9c48ea2f36fdadf18891d
-rw-r--r-- | src/libsystemd/sd-device/device-enumerator.c | 3 |
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 a1932f41f9..4ddc47aac5 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -480,7 +480,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; |