Skip to content

daemon: warn at startup when running as PID 1 - #496

Merged
TeoSlayer merged 2 commits into
mainfrom
fix/daemon-pid1-warning
Oct 7, 2026
Merged

TeoSlayer merged 2 commits into
mainfrom
fix/daemon-pid1-warning

Conversation

@TeoSlayer

Copy link
Copy Markdown
Collaborator

Pull Request

Summary

In a container where pilot-daemon is PID 1, servers that apps start and daemonize (redis-server, postgres) are re-parented to it and stay as zombies when stopped: Go does not reap children it did not start. Seen in a lab as Z processes under PID 1.

Changes

  • One warning at startup on Linux when the daemon is PID 1, saying orphaned app processes will not be reaped and to run under an init.
  • README: docker run --init, Compose init: true, or tini as the entrypoint.

No reaper is added, deliberately. A wait4(-1) loop steals exit statuses from exec.Cmd.Wait: in an experiment it lost 17 of 300, which in the app supervisor becomes exit code -1 with the real code gone.

Test Plan

  • go build ./..., go vet ./..., unit suite with GOWORK=off
  • Tests for linux pid 1, linux other pids, and non-linux pid 1
  • Real linux daemon in a container: warns once as the entrypoint, not at all under --init

Checklist

  • New code includes the SPDX license header
  • go.mod / go.sum unchanged
  • CHANGELOG updated

🤖 Generated with Claude Code

Teo Calin and others added 2 commits October 7, 2026 15:56
As the entrypoint of a container started without an init, the daemon is
handed every orphaned process. The servers its apps start daemonize
(redis-server, postgres), so they end up as children of PID 1 and stay
zombies after they are stopped: Go only waits for children it started.

The daemon does not reap them. A wait for any child also takes the exit
status of the apps the supervisor is waiting on (measured: 17 of 300
exec.Cmd.Run calls failed with "waitid: no child processes" next to a
wait4(-1) loop). Reaping belongs to an init process, so on Linux the daemon
now logs one warning when it is PID 1, and the README's install notes say
to use `docker run --init` or tini.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d changelog wording

From review: Kubernetes and Fargate have no --init, so name
shareProcessNamespace and initProcessEnabled; say zombies count against
the container's PID limit and that no warning does not prove another PID 1
reaps; fix the changelog's tense and a test comment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TeoSlayer
TeoSlayer force-pushed the fix/daemon-pid1-warning branch from 6e45139 to 090e8ff Compare October 7, 2026 13:09
@TeoSlayer
TeoSlayer merged commit 8cd62ac into main Oct 7, 2026
14 checks passed
@TeoSlayer
TeoSlayer deleted the fix/daemon-pid1-warning branch October 7, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant