diff --git a/configure.ac b/configure.ac index 4cd14c79..89e1794d 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ AC_CONFIG_FILES([Makefile man/Makefile plugins/Makefile src/Makefile - system/Makefile + system/Makefile system/10-hotplug.conf tmpfiles.d/Makefile test/test.env test/Makefile test/lib/Makefile test/src/Makefile]) diff --git a/src/Makefile.am b/src/Makefile.am index 844964d4..ff3aca05 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,8 @@ if WATCHDOGD pkglibexec_PROGRAMS += watchdogd endif +dist_pkglibexec_SCRIPTS = coldplug + finit_pkglibdir = $(pkglibdir) finit_pkglib_SCRIPTS = rescue.conf sample.conf diff --git a/src/coldplug b/src/coldplug new file mode 100755 index 00000000..5610c080 --- /dev/null +++ b/src/coldplug @@ -0,0 +1,11 @@ +#!/bin/sh + +# With the daemon mode ('mdev -df') we no longer need the hotplug helper +echo "" > /proc/sys/kernel/hotplug + +# Wait for 'mdev -df' to set up its event queue. +sleep 1 + +# Trigger 'add' event for all devices and subsystems to load all modules +# and any firmware needed by the hardware. +find /sys/devices -name uevent -print | while IFS='' read X; do echo add > $X; done diff --git a/system/10-hotplug.conf b/system/10-hotplug.conf deleted file mode 100644 index 10cd2f60..00000000 --- a/system/10-hotplug.conf +++ /dev/null @@ -1,17 +0,0 @@ -# System hotplug can be handled by udev or mdev - -# Either we have systemd-udevd or eudev, on the rare occasion we find -# both, we opt for the latter. Remember, you can override this by a -# custom hotplug.conf in /etc/finit.d/ or /etc/finit.d/enabled/. -service nowarn [S12345789] cgroup.system name:udevd pid:udevd log /lib/systemd/systemd-udevd -- Device event managing daemon (udev) -service nowarn [S12345789] cgroup.system name:udevd pid:udevd log udevd -D -- Device event managing daemon (udev) - -# Wait for udevd to start, then wait a couple of seconds for it to become ready -run nowarn if:udevd cgroup.init :1 [S] log udevadm settle -t 0 -- -run nowarn if:udevd cgroup.init :2 [S] log udevadm control --reload -- -run nowarn if:udevd cgroup.init :3 [S] log udevadm trigger -c add -t devices -- Requesting device events -run nowarn if:udevd cgroup.init :4 [S] log udevadm trigger -c add -t subsystems -- Requesting subsystem events -run nowarn if:udevd cgroup.init :5 [S] log udevadm settle -t 30 -- Waiting for udev to finish - -# If udevd is not available, try mdev -run nowarn conflict:udevd [S] mdev -s -- Populating device tree diff --git a/system/10-hotplug.conf.in b/system/10-hotplug.conf.in new file mode 100644 index 00000000..5c14ca7e --- /dev/null +++ b/system/10-hotplug.conf.in @@ -0,0 +1,42 @@ +# System hotplug handled by udev or mdev +# +# Your system usually has either udevd, mdev, or mdevd. They probe the system +# for devices, loading modules and any firmware needed. Since the bootstrap +# often needs to be synchronized carefully, we suggest using your system log +# daemon as the barrier for all other services. E.g.: +# +# service if:udevd [S0123456789] syslogd -F -- System log daemon +# service if:mdev [S0123456789] syslogd -F -- System log daemon +# +# This provdes a condition that can act as a barrier for all +# other services. Notice the `if:` statement and the condition for starting +# syslogd is only considered if either udevd or mdev (service) is loaded and +# is guaranteed to run after each respective run stanza have completed. +# +# Override this file by copying it to /etc/finit.d/, using the same name, then +# change the contents any way you like, it can even be empty. + +# Check for systemd-udevd and eudev, if we find both, we opt for the latter. +service nowarn [S12345789] cgroup.system name:udevd pid:udevd log /lib/systemd/systemd-udevd -- Device event daemon (udev) +service nowarn [S12345789] cgroup.system name:udevd pid:udevd log udevd -D -- Device event daemon (udev) + +# Wait for udevd to start, then trigger coldplug events and module loading. +# The last 'settle' call waits for it to finalize processing all uevents. +run nowarn if:udevd cgroup.init :1 [S] log udevadm settle -t 0 -- +run nowarn if:udevd cgroup.init :2 [S] log udevadm control --reload -- +run nowarn if:udevd cgroup.init :3 [S] log udevadm trigger -c add -t devices -- Requesting device events +run nowarn if:udevd cgroup.init :4 [S] log udevadm trigger -c add -t subsystems -- Requesting subsystem events +run nowarn if:udevd cgroup.init :5 [S] log udevadm settle -t 30 -- Waiting for udev to finish + +# If udevd is not available, try mdev. The "new" daemon mode (-df) was added +# in BusyBox 1.31.0, 2019. It calls `mdev -s` internally but does not create +# a PID file when that is done, so synchronization with coldplug is fragile. +service nowarn conflict:udevd cgroup.init \ + [S12345789] mdev -df -S -- Device event daemon (mdev) + +# Trigger a replay of all uevents from boot, before userspace was up and the +# filesystem mounted. Compared to udevd, we don't know when 'mdev -df' has +# finished processing all events, i.e., depending on is +# not an indicator of all devices having been (re)discovered and fully set up. +run nowarn conflict:udevd cgroup.init name:coldplug if: \ + [S] @pkglibexecdir@/coldplug -- Cold plugging system diff --git a/system/Makefile.am b/system/Makefile.am index 2cd7824c..5dac235b 100644 --- a/system/Makefile.am +++ b/system/Makefile.am @@ -1,8 +1,10 @@ +EXTRA_DIST = 10-hotplug.conf.in systemdir = $(system_path) +system_DATA = dist_system_DATA = if BUILD_HOTPLUG_PLUGIN -dist_system_DATA += 10-hotplug.conf +system_DATA += 10-hotplug.conf endif if BUILD_TESTSERV_PLUGIN