dhcpcd: Fix startup process

The *dhcpcd.service* systemd unit file that ships with Buildroot is
broken.  It orders the unit after *network.target*, which makes no
sense.  It also configures the process to fork, but incorrectly
configures the PID file.  Finally, by relying on the fork to indicate
that the network is "online," it does not distinguish between "an
interface is up" and "the network is reachable."  As most daemons only
need the former, they only rely on *network.target*, and thus can fail
to start correctly.

To correct this brokenness, we provide our own unit file for
*dhcpcd.service*, based on the one included in the Fedora *dhcpcd* RPM
package.  For "online" signalling, we provide a pair of shell scripts:
one reads from a named pipe waiting for a message and the other sends a
message to the pipe when configuration is complete.
pull/2/head
Dustin 2022-06-27 10:25:07 -05:00
parent 47d19c033b
commit 52e28b6912
8 changed files with 77 additions and 4 deletions

View File

@ -0,0 +1,16 @@
[Unit]
Description=Wait for Network to be Configured
DefaultDependencies=no
Conflicts=shutdown.target
After=dhcpcd.service
Requires=dhcpcd.service
Before=network-online.target shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/libexec/dhcpcd-wait-online
TimeoutStartSec=1m
RemainAfterExit=yes
[Install]
WantedBy=network-online.target

View File

@ -0,0 +1,20 @@
#!/bin/sh
# After it finishes configuring a network interface, dhcpcd will write
# `online` to the `/run/dhcpcd/wait-online` pipe, if it exists.
# Reading from the pipe will block until something is written to it,
# allowing us to wait for the network to be configured, without
# repeatedly polling interface information.
#
# If anything but `online` is read from the pipe, we assume that there
# was an error configuring the network.
cleanup() {
rm -f /run/dhcpcd/wait-online
}
mkdir -p /run/dhcpcd
mkfifo /run/dhcpcd/wait-online || exit $?
trap cleanup INT TERM QUIT EXIT
status=$(cat /run/dhcpcd/wait-online)
test "${status}" = online

14
package/dhcpcd/dhcpcd.mk Normal file
View File

@ -0,0 +1,14 @@
define DHCPCD_INSTALL_INIT_SYSTEMD
$(INSTALL) -D -m u=rw,go=r \
$(BR2_EXTERNAL_metricspi_PATH)/package/dhcpcd/dhcpcd.service \
$(TARGET_DIR)/usr/lib/systemd/system/dhcpcd.service
$(INSTALL) -D -m u=rw,go=r \
$(BR2_EXTERNAL_metricspi_PATH)/package/dhcpcd/dhcpcd-wait-online.service \
$(TARGET_DIR)/usr/lib/systemd/system/dhcpcd-wait-online.service
$(INSTALL) -D -m u=rwx,go=rx \
$(BR2_EXTERNAL_metricspi_PATH)/package/dhcpcd/online.hook.sh \
$(TARGET_DIR)/usr/lib/dhcpcd/dhcpcd-hooks/99-online
$(INSTALL) -D -m u=rwx,go=rx \
$(BR2_EXTERNAL_metricspi_PATH)/package/dhcpcd/dhcpcd-wait-online.sh \
$(TARGET_DIR)/usr/libexec/dhcpcd-wait-online
endef

View File

@ -0,0 +1,10 @@
[Unit]
Description=A minimalistic network configuration daemon with DHCPv4, rdisc and DHCPv6 support
Wants=network.target
Before=network.target
[Service]
ExecStart=/usr/sbin/dhcpcd -q --nobackground
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,16 @@
#!/bin/sh
# If the `/run/dhcpcd/wait-online` named pipe is present, it means
# the *dhcpcd-wait-online.service* systemd unit is active. This unit
# helps order the activation of other units, especially during bootup.
# Once the interface is configured and active, we write a message to
# the pipe to indicate that the boot process can continue and services
# that require the network to be online can be started.
if $if_configured; then
if $if_up; then
if [ -p /run/dhcpcd/wait-online ]; then
echo online > /run/dhcpcd/wait-online
fi
fi
fi

View File

@ -1,6 +1,7 @@
enable chrony-wait.service
enable dhcpcd.service
enable dhcpcd-wait-online.service
enable dbus.socket
enable dbus-broker.service

View File

@ -1,2 +0,0 @@
[Unit]
Before=network-online.target

View File

@ -1,2 +0,0 @@
[Service]
PIDFile=/run/dhcpcd/pid