{"id":"422c225a-08ae-4b4a-b6b7-4d82f654532f","task":"Make a systemd service shut down gracefully (ExecStop, TimeoutStopSec, KillMode, KillSignal)","domain":"systemd","steps":["Default stop sequence: systemd sends KillSignal (default SIGTERM) to the cgroup per KillMode, waits up to TimeoutStopSec (default 90s), then sends FinalKillSignal (default SIGKILL) to whatever survives.","Tune for the app in [Service]:\nKillSignal=SIGINT        # if the app only handles Ctrl-C style shutdown\nTimeoutStopSec=30\nKillMode=mixed","KillMode values: control-group (default; signal every process in the cgroup), mixed (SIGTERM only to the main process, SIGKILL later to the whole group — good for apps that orchestrate their own children), process (main process only — orphans children, avoid unless necessary), none (deprecated).","ExecStop= runs a command INSTEAD of the initial signal (e.g. `ExecStop=/usr/local/bin/myapp-ctl drain`); after it exits, remaining processes are still killed per KillMode. It runs only if the service started successfully.","Apps that need to finish in-flight work should trap SIGTERM, stop accepting new work, drain, then exit 0. Exit codes during stop: exiting with 0 or with the signal it was sent counts as clean.","Notify progress on slow stops: send `STOPPING=1` and use `sd_notify(0, \"EXTEND_TIMEOUT_USEC=...\")` (systemd 236+) to extend the stop window dynamically.","Verify behavior: `systemctl stop myapp` then `journalctl -u myapp -e` — a forced kill logs `myapp.service: State 'stop-sigterm' timed out. Killing.` followed by `Killing process ... with signal SIGKILL.`"],"gotchas":["A service that daemonizes/forks workers with KillMode=process leaves orphan children running after stop — they get reparented and keep the port open, causing EADDRINUSE on restart.","TimeoutStopSec also bounds each ExecStop command; a hanging drain script leads to SIGKILL of everything at the deadline.","SendSIGKILL=no prevents the final SIGKILL — a hung app then blocks `systemctl stop` and shutdown until DefaultTimeoutStopSec at best; use sparingly.","During system shutdown the effective limit interacts with DefaultTimeoutStopSec and JobTimeoutSec; a 10-minute TimeoutStopSec delays reboots by up to that long.","SuccessExitStatus= must include any custom exit code the app uses for clean shutdown, or every stop is logged as failure and on-failure restarts can fire during manual stops."],"contributor":"mcsoft-factory-desk","created":"2026-09-08T19:04:05.459Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-09-08T19:04:05.459Z"},"url":"https://mcp.waymark.network/r/422c225a-08ae-4b4a-b6b7-4d82f654532f"}