On Sun, 6 Sep 2026 11:37:40 +0300 Martin-Éric Racine wrote:
> bin:dhcpcd-base doesn't ship any systemd unit or or init.d script;
> bin:dhcpcd does. Reassigning accordingly.

Understood, and agreed -- I filed it against the wrong binary package.
Thanks for reassigning.

> This being said, we indeed don't currently restart after an upgrade.
> Would the following change do what you need?

Yes. I built your diff and tested it; it fixes the bug.

Test: a forky/sid amd64 VM running the 1:10.3.2-6 manager, interface
configured by ifupdown (iface enp1s0 inet dhcp), upgraded to a package
built with your change.

  before upgrade: manager=dhcpcd-10.3.2  pkg=1:10.3.2-6
  after  upgrade: manager=dhcpcd-10.5.2  pkg=1:10.5.2-2~varA
  control command (dhcpcd -n enp1s0): returned in 0s, exit 0
  network across the restart: enp1s0 UP 172.31.0.122/24 (unchanged)

and the symptom I originally reported, on the next reboot:

  Sep 06 11:01:23 testy systemd-logind[431]: System is rebooting.
  Sep 06 11:01:23 testy systemd[1]: Stopping networking.service...
  Sep 06 11:01:23 testy ifdown[5282]: sending commands to dhcpcd process
  Sep 06 11:01:23 testy systemd[1]: networking.service: Deactivated 
successfully.
  Sep 06 11:01:24 testy systemd[1]: Shutting down.

All within a second, against the ~3 minutes and a SIGKILL before.

The restart is safe for the running configuration because /etc/dhcpcd.conf
ships "persistent", so addresses and routes survive it, as the unchanged
address above shows.

TWO SIDE EFFECTS OF DROPPING --no-start, IN CASE THEY ARE UNINTENDED

Your diff drops --no-start as well as flipping --no-restart-after-upgrade.
That selects debhelper's postinst-systemd-restart snippet, which does

        if [ -n "$2" ]; then _dh_action=restart; else _dh_action=start; fi
        deb-systemd-invoke $_dh_action 'dhcpcd.service'

so besides the fix it also changes two things I measured:

  * fresh install now starts the daemon
      after purge + install: is-enabled=enabled is-active=active
      (previously it was enabled but left inactive until the next boot)

  * upgrading while the admin has dhcpcd.service stopped now starts it
      before upgrade: is-active=inactive
      after  upgrade: is-active=active

If you want those, your diff is exactly right and I am happy with it.

If you would rather keep --no-start, then keeping it *and* passing
--restart-after-upgrade explicitly also fixes the bug:

        dh_installsystemd --name=dhcpcd --no-start --no-stop-on-upgrade 
--restart-after-upgrade

An explicitly passed --restart-after-upgrade survives the -r side effect
(dh_installsystemd lines 183-184), and combined with --no-start it selects
postinst-systemd-restartnostart, which emits

        if [ -n "$2" ]; then
                deb-systemd-invoke try-restart 'dhcpcd.service'
        fi

try-restart restarts only a service that is already running, and only on
upgrade. I tested this variant too:

                                  your diff        with --no-start kept
  upgrade, service running        restarted        restarted
  upgrade, service stopped        started          left stopped
  fresh install                   started          left stopped

Both fix the reported hang. The difference is only in the two rows that are
not the bug.

One thing that argues for your version: with --no-start kept, dh_installinit
emits no invoke-rc.d call at all, so on a non-systemd system the daemon is
not restarted and the bug persists there. Your diff does cover that case.
Conversely, your version's init snippet is

        invoke-rc.d --skip-systemd-native dhcpcd $_dh_action || exit 1

where a failed start leaves the package unconfigured; that is debhelper's
normal behaviour, just worth knowing.

I have no strong preference between the two -- you know the package's
history better than I do. Either resolves what I reported.

(I had also prepared a debian/dhcpcd.postinst doing a conditional restart,
which may have crossed with your mail. Your debian/rules change is simpler
and I would drop mine in favour of it.)

TWO SMALL NOTES

The dhcpcd@ line in your diff is a no-op: template units cannot be started
or enabled directly, and dh_installsystemd emits nothing for dhcpcd@ in
postinst, prerm or postrm with either flag set. So a running
dhcpcd@<iface>.service instance still keeps the old binary across an
upgrade. Not my case, and probably rare, but it is not covered by either
variant.

I also reported the other half upstream -- that the client blocks in read(2)
forever rather than timing out -- with a patch:

  https://github.com/NetworkConfiguration/dhcpcd/issues/723
  https://github.com/NetworkConfiguration/dhcpcd/pull/724

That makes a mismatched pair recover after 5s with a warning instead of
hanging, but it only helps once the client side is new enough to contain it.
Restarting the daemon on upgrade is what actually prevents the mismatch on
Debian, so the two are complementary.

Thanks for the quick turnaround.

Cheers,
Thomas

Reply via email to