A service is not launched until its on= readiness condition is met, even though it is PENDING. The gate is evaluated each loop iteration so a service gated on on=up:X (or a socket / time / net condition) launches the moment X becomes ready.
| on= | Ready when |
|---|---|
| all | immediately (default). |
| up:X | service X has reached ready. |
| net | any non-lo interface is up. |
| sock:tcp:port | a connect to 127.0.0.1:port succeeds. |
| sock:unix:path | a connect to the unix socket path succeeds. |
| time:ms | ms of monotonic boot time have elapsed. |
On a child exit, fx-init applies the service's restart policy: always restarts unconditionally, on-failure only on a non-zero exit, never leaves it stopped/failed. A restarting service is held in BACKOFF until its next_start deadline.
Backoff is in milliseconds: the sleep is fx_backoff_sleep_ms(cur, base) (base defaults to 1000, capped at 30 s), and the next accumulated backoff is the slept value doubled, capped. A service that stays STARTED for 60 s without crashing earns a reset of its accumulated backoff to base, so a later crash restarts promptly instead of at the doubled value it had reached during a flappy boot.
An explicitly-stopped service (fxctl stop sets ST_STOPPED before the kill) is excluded from both restart and the boot start-failure accounting — it was intentional, not a crash.
A service with a probe stays STARTED but not ready until its probe succeeds. A service with no probe is ready the moment it is STARTED. The tcp / unix probes share the exact connect contract with on=sock:tcp/unix — a successful connect means the service is accepting.
A single waitpid(-1, WNOHANG) drain reaps every child. For a reaped service, fx-init records the exit, applies the restart policy, and — if the exit happened during the boot grace window and the service was not explicitly stopped — pins boot_status failed and sets g_boot_decided so evaluate_boot_ok can never flip it to ok. After boot-ok, exits restart in place and never touch boot_status.