Service startup ordering race conditions in Debian's systemd parallel initialization
0 reputation · 28 May 2023, 20:58 UTC
0 reputation · 28 May 2023, 20:58 UTC
Debian's systemd service manager resolves dependencies using After=, Before=, Wants=, and Requires= directives in unit files. When services have no direct interdependencies, systemd may start them in parallel, which can cause race conditions if services expect sequential startup. The Type= directive (simple, forking, oneshot, notify, dbus, idle) affects startup behavior, and the Restart= directive controls failure responses.
However, the interaction between systemd's parallel startup behavior and services that implicitly depend on other services being fully initialized remains an unresolved design question. For instance, a service might assume a database socket exists without explicitly declaring the dependency.
Questions:
1. How can administrators reliably detect services that have implicit ordering dependencies not declared in unit files?
2. What is the recommended approach for handling services that need to wait for filesystem mounts or network availability before starting?
3. When should After= be used versus Wants= or Requires= for different dependency scenarios?
32275 reputation · 28 May 2023, 21:09 UTC
Likely explanation: When a service starts before a resource it assumes exists (e.g., a socket, mount point, or network interface) but does not declare that dependency, systemd’s parallel start can cause the service to fail or retry, leaving traces in the journal.
systemd.log_level=debug to the kernel command line or /etc/systemd/system.conf) and reboot.journalctl -b | grep -E '(Starting|Started|Failed)' to see start timestamps.systemd-analyze dot | dot -Tpng > deps.png and compare with the observed order.Likely explanation: Services that need a mount point or network interface should not rely on implicit ordering; they must declare an explicit dependency on the appropriate target unit.
After=local-fs.target and Wants=local-fs.target (use Requires= only if the mount is essential for the service to function).After=network-online.target and Wants=network-online.target; ensure systemd-networkd-wait-online.service (or the equivalent for NetworkManager) is enabled.systemctl daemon-reload then systemctl status <unit> to verify the new lines appear.Likely explanation: After= only influences ordering; it does not pull the other unit into the transaction. Wants= adds a soft dependency (the unit is started if available but does not block the dependent if missing). Requires= adds a hard dependency (the dependent will not start unless the required unit is active, and will be stopped if the required unit fails).
After= together with Wants= when you want the service to start after another unit but can tolerate its absence (e.g., optional logging service).After= with Requires= when the service cannot function without the other unit (e.g., a web server that needs a database).Requires= for non‑essential units; a missing required unit will block boot or cause the dependent to stop unexpectedly.After=/Requires= with an ExecStartPre= readiness check (e.g., pg_isready for PostgreSQL) and keep the check lightweight and timeout‑safe.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.