From 52e28b69125cc9392494c742cbbe69f131f3b3d7 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Mon, 27 Jun 2022 10:25:07 -0500 Subject: [PATCH] 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. --- package/dhcpcd/dhcpcd-wait-online.service | 16 +++++++++++++++ package/dhcpcd/dhcpcd-wait-online.sh | 20 +++++++++++++++++++ package/dhcpcd/dhcpcd.mk | 14 +++++++++++++ package/dhcpcd/dhcpcd.service | 10 ++++++++++ package/dhcpcd/online.hook.sh | 16 +++++++++++++++ .../systemd/system-preset/90-default.preset | 1 + .../before-network-online.conf | 2 -- .../system/dhcpcd.service.d/pidfile.conf | 2 -- 8 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 package/dhcpcd/dhcpcd-wait-online.service create mode 100644 package/dhcpcd/dhcpcd-wait-online.sh create mode 100644 package/dhcpcd/dhcpcd.mk create mode 100644 package/dhcpcd/dhcpcd.service create mode 100644 package/dhcpcd/online.hook.sh delete mode 100644 rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/before-network-online.conf delete mode 100644 rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/pidfile.conf diff --git a/package/dhcpcd/dhcpcd-wait-online.service b/package/dhcpcd/dhcpcd-wait-online.service new file mode 100644 index 0000000..0164936 --- /dev/null +++ b/package/dhcpcd/dhcpcd-wait-online.service @@ -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 diff --git a/package/dhcpcd/dhcpcd-wait-online.sh b/package/dhcpcd/dhcpcd-wait-online.sh new file mode 100644 index 0000000..2b6afae --- /dev/null +++ b/package/dhcpcd/dhcpcd-wait-online.sh @@ -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 diff --git a/package/dhcpcd/dhcpcd.mk b/package/dhcpcd/dhcpcd.mk new file mode 100644 index 0000000..bec7ae7 --- /dev/null +++ b/package/dhcpcd/dhcpcd.mk @@ -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 diff --git a/package/dhcpcd/dhcpcd.service b/package/dhcpcd/dhcpcd.service new file mode 100644 index 0000000..86b5a43 --- /dev/null +++ b/package/dhcpcd/dhcpcd.service @@ -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 diff --git a/package/dhcpcd/online.hook.sh b/package/dhcpcd/online.hook.sh new file mode 100644 index 0000000..1922c6e --- /dev/null +++ b/package/dhcpcd/online.hook.sh @@ -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 diff --git a/rootfs/overlay/usr/lib/systemd/system-preset/90-default.preset b/rootfs/overlay/usr/lib/systemd/system-preset/90-default.preset index 56feca4..24b92d3 100644 --- a/rootfs/overlay/usr/lib/systemd/system-preset/90-default.preset +++ b/rootfs/overlay/usr/lib/systemd/system-preset/90-default.preset @@ -1,6 +1,7 @@ enable chrony-wait.service enable dhcpcd.service +enable dhcpcd-wait-online.service enable dbus.socket enable dbus-broker.service diff --git a/rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/before-network-online.conf b/rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/before-network-online.conf deleted file mode 100644 index 7c58381..0000000 --- a/rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/before-network-online.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Unit] -Before=network-online.target diff --git a/rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/pidfile.conf b/rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/pidfile.conf deleted file mode 100644 index 2d903c1..0000000 --- a/rootfs/overlay/usr/lib/systemd/system/dhcpcd.service.d/pidfile.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Service] -PIDFile=/run/dhcpcd/pid