Merge pull request #504 from crosbymichael/pid1-fixes

Fix pdeathsig and ppid for supervisor running as pid1
This commit is contained in:
Alexander Morozov 2015-04-02 14:09:47 -07:00
commit d00b836985
3 changed files with 11 additions and 6 deletions

View File

@ -140,7 +140,9 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
cmd.SysProcAttr = &syscall.SysProcAttr{} cmd.SysProcAttr = &syscall.SysProcAttr{}
} }
cmd.ExtraFiles = []*os.File{childPipe} cmd.ExtraFiles = []*os.File{childPipe}
cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL // NOTE: when running a container with no PID namespace and the parent process spawning the container is
// PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason
// even with the parent still running.
if c.config.ParentDeathSignal > 0 { if c.config.ParentDeathSignal > 0 {
cmd.SysProcAttr.Pdeathsig = syscall.Signal(c.config.ParentDeathSignal) cmd.SysProcAttr.Pdeathsig = syscall.Signal(c.config.ParentDeathSignal)
} }

View File

@ -69,7 +69,8 @@ func newContainerInit(t initType, pipe *os.File) (initer, error) {
}, nil }, nil
case initStandard: case initStandard:
return &linuxStandardInit{ return &linuxStandardInit{
config: config, parentPid: syscall.Getppid(),
config: config,
}, nil }, nil
} }
return nil, fmt.Errorf("unknown init type %q", t) return nil, fmt.Errorf("unknown init type %q", t)

View File

@ -13,7 +13,8 @@ import (
) )
type linuxStandardInit struct { type linuxStandardInit struct {
config *initConfig parentPid int
config *initConfig
} }
func (l *linuxStandardInit) Init() error { func (l *linuxStandardInit) Init() error {
@ -85,9 +86,10 @@ func (l *linuxStandardInit) Init() error {
if err := pdeath.Restore(); err != nil { if err := pdeath.Restore(); err != nil {
return err return err
} }
// Signal self if parent is already dead. Does nothing if running in a new // compare the parent from the inital start of the init process and make sure that it did not change.
// PID namespace, as Getppid will always return 0. // if the parent changes that means it died and we were reparened to something else so we should
if syscall.Getppid() == 1 { // just kill ourself and not cause problems for someone else.
if syscall.Getppid() != l.parentPid {
return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
} }
return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())