scope sleep to homelab, and port the boot hang fix

Sleep and suspend is homelab only now. The two exclusions are for different
reasons and both are stated in the run rather than left implicit:

  dev — a laptop should sleep; disabling it is a hot bag and a flat battery.

  vps — not merely unnecessary, harmful. A virtual machine has no lid and no
  power button, but the provider's Shut down control works by sending an ACPI
  power button event. HandlePowerKey=ignore makes the VM ignore it, so graceful
  shutdown requests silently do nothing and the instance is hard-killed instead.
  systemd defaults that key to poweroff for exactly this reason.

The boot hang fix is everything except vps, where systemd-networkd genuinely
manages the network and the unit is load-bearing.

Rather than asking whether boot "feels slow" — a question people answer from
memory of the worst time it happened — the step prints what the unit actually
cost on this boot, from systemd's own accounting. On this host that is 14ms,
which ends the discussion. On a NetworkManager desktop it is two minutes, which
also ends it. On dev the wording says outright that a small number here means
there is nothing to do.

The original's live guard is kept and is what actually decides: NetworkManager
active and networkd not. Anything else, including "cannot tell", is left alone,
and the reason is printed. The warning against disabling systemd-networkd
outright is carried across into the library, where the alternative would be
attempted.

Verified all three roles on this host, which is a networkd machine: homelab and
dev both correctly refuse and explain, vps skips as not applicable, and the
timing helper reads 14ms out of systemd-analyze.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 18:17:17 +00:00
co-authored by Claude Opus 5
parent c87127ff93
commit 458510a0a8
2 changed files with 123 additions and 3 deletions
+46
View File
@@ -438,6 +438,52 @@ disable_sleep() {
systemctl restart systemd-logind
}
# -----------------------------------------------------------------------------
# Boot hang
# -----------------------------------------------------------------------------
#
# systemd-networkd-wait-online blocks boot until the network is up. Where
# systemd-networkd actually manages the network — a server or cloud image, via
# cloud-init and netplan — it does that in milliseconds and is load-bearing.
#
# Where NetworkManager owns the network instead, systemd-networkd runs nothing,
# but the wait-online unit is still enabled and waits for a link that will never
# be configured. It gives up after its full timeout, on every boot.
#
# So the fix is masking one unit, and only on the second stack. Do NOT
# `systemctl disable --now systemd-networkd` to achieve the same thing: on a
# networkd-managed box that brings it up with no network on the next boot, no
# ssh, and nothing but the provider's rescue console.
WAIT_ONLINE_UNIT=systemd-networkd-wait-online.service
network_manager_name() {
if systemctl is-active --quiet NetworkManager.service 2>/dev/null; then
echo "NetworkManager"
elif systemctl is-active --quiet systemd-networkd.service 2>/dev/null; then
echo "systemd-networkd"
else
echo "neither — unclear"
fi
}
# Is the wait actually pointless here? NetworkManager in charge and networkd not.
# Anything else, including "cannot tell", is left alone.
wait_online_is_spurious() {
systemctl is-active --quiet NetworkManager.service 2>/dev/null &&
! systemctl is-active --quiet systemd-networkd.service 2>/dev/null
}
# What that unit actually cost on this boot, straight from systemd's own
# accounting. Worth printing rather than asking somebody whether boot "feels
# slow": the answer is either 14ms or two minutes, and there is no arguing with
# it. Empty when the unit did not run.
wait_online_boot_time() {
systemd-analyze blame 2>/dev/null | awk -v u="$WAIT_ONLINE_UNIT" '$NF == u { $NF = ""; sub(/[[:space:]]+$/, ""); print; exit }'
}
mask_wait_online() { systemctl mask --now "$WAIT_ONLINE_UNIT" >/dev/null 2>&1; }
# -----------------------------------------------------------------------------
# Timezone
# -----------------------------------------------------------------------------