NS-026
documentedacknowledgement-mistaken-for-readiness
systemd reports a Type=simple unit active before the service binary has been executed
- reads as
- `systemctl start app` returns and `systemctl is-active app` says active. Conclusion drawn: the service is up and accepting connections.
- actually
- For Type=simple the service manager considers the unit started immediately after the main service process has been forked off — after fork() and before the new process has called execve() to invoke the actual service binary. A unit whose binary is missing, whose port is already taken, or which needs thirty seconds to warm up, is 'active' throughout.
- blind because
- The process list reports existence and state. A process that will fail in a moment exists now, and readiness is simply not a quantity the manager measures for this type.
- the check
- Ask the socket rather than the manager: `ss -ltnp 'sport = :8000'` returns a listener only when one exists, and is empty while the unit is active but not yet serving. A single request to the port distinguishes the same two states.
- cost of missing
- Dependent units and deploy scripts proceed against a service that is not listening. The ordering guarantee that was assumed was never offered.
- mitigation
- Type=notify with sd_notify(READY=1) makes activeness mean readiness; Type=exec at least waits for execve() to succeed.
- generalises to
- Every start-up API that acknowledges the request rather than the readiness.
- source
- freedesktop.org