]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device-enumerator: do not return error when a device is removed
authorINSUN PYO <insun.pyo@samsung.com>
Thu, 19 Nov 2020 01:49:04 +0000 (10:49 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 24 Nov 2020 12:38:19 +0000 (21:38 +0900)
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
*******************************************************************************************************

src/libsystemd/sd-device/device-enumerator.c

index 6888b58b67a6cb4e3872a1a22830d4d93578a467..3641348881c02fe4fcf58569e1542c8f0af42dc1 100644 (file)
@@ -420,7 +420,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;