]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/device: verify device syspath on switching root 25132/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 25 Oct 2022 16:18:05 +0000 (01:18 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 26 Oct 2022 21:11:10 +0000 (06:11 +0900)
Otherwise, if a device is removed while switching root, then the
corresponding .device unit will never go to inactive state.

This replaces the code dropped by cf1ac0cfe44997747b0f857a1d0b67cea1298272.

Fixes #25106.

src/core/device.c

index 7e354b2b4a73fbd7e3c0f90801cb0b2a60a92456..6e07f2745b4d754e1653b06496a6e22305487b39 100644 (file)
@@ -305,6 +305,19 @@ static int device_coldplug(Unit *u) {
                 found &= ~DEVICE_FOUND_UDEV;
                 if (state == DEVICE_PLUGGED)
                         state = DEVICE_TENTATIVE;
+
+                /* Also check the validity of the device syspath. Without this check, if the device was
+                 * removed while switching root, it would never go to inactive state, as both Device.found
+                 * and Device.enumerated_found do not have the DEVICE_FOUND_UDEV flag, so device_catchup() in
+                 * device_update_found_one() does nothing in most cases. See issue #25106. Note that the
+                 * syspath field is only serialized when systemd is sufficiently new and the device has been
+                 * already processed by udevd. */
+                if (d->deserialized_sysfs) {
+                        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+
+                        if (sd_device_new_from_syspath(&dev, d->deserialized_sysfs) < 0)
+                                state = DEVICE_DEAD;
+                }
         }
 
         if (d->found == found && d->state == state)