krallin / tini

A tiny but valid `init` for containers
MIT License
9.82k stars 507 forks source link

tini is not reaping zombine child processes inside the container #138

Closed ahmetb closed 5 years ago

ahmetb commented 5 years ago

Inside a docker container I'm running tini-static v0.18.0 and it runs a Go program.

This go program executes a /bin/sh, -c, sleep 999999 && sleep 99999 in the background (doesn't wait() for it) but it just gets its pid:

    cmd := exec.Command("/bin/sh", "-c", "sleep 1000000 && sleep 5")
    cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
    if err := cmd.Start(); err != nil {
        fmt.Fprintf(w, "failed to start process %d: %v", err)
        return
    }
    fmt.Fprintf(w, "started process pid=%d", cmd.Process.Pid)

You'll note that I have Setpgid: true as an exec option above, which creates a new "process group" that has the same ID as this new process's PID.

So when the Go program starts, the process tree looks like this:

pid=1 [ppid=0,pgrp=1] (S) tini
  pid=8 [ppid=1,pgrp=8] (S) server
    pid=14 [ppid=8,pgrp=14] (S) sh
      pid=15 [ppid=14,pgrp=14] (S) sleep

Now, I hit an endpoint that kills this sh process with SIGKILL. To do that I'm actually using kill with negative value of the sh's PID (-14). In go this looks like:

syscall.Kill(-14, syscall.SIGKILL)

and it's equivalent to GNU kill -KILL -14 command.

Once kill is issued, I observe three things:

  1. sh process is now a zombie (Z) and is not reparented to tini but still under server
  2. sleep (subprocess of "sh") is now gone:
pid=1 [ppid=0,pgrp=1] (S) tini
  pid=8 [ppid=1,pgrp=8] (S) server
    pid=14 [ppid=8,pgrp=14] (Z) sh

Is this expected?

corneliusweig commented 5 years ago

I think this is expected, as tini acts as an init process. If any init process were to reap a grand-child zombie, the init's child would no longer have the possibility to query the status of the grand-child (i.e. it's child). But the child may be interested in the grandchild's exit status.

krallin commented 5 years ago

Yeah, @corneliusweig is entirely correct here, this is indeed expected. Processes will only be re-parented to Tini once their parent dies.

ahmetb commented 5 years ago

Thanks.