diff --git a/libcontainer/configs/namespaces_syscall.go b/libcontainer/configs/namespaces_syscall.go index 0516dba8d..543e059aa 100644 --- a/libcontainer/configs/namespaces_syscall.go +++ b/libcontainer/configs/namespaces_syscall.go @@ -31,3 +31,15 @@ func (n *Namespaces) CloneFlags() uintptr { } return uintptr(flag) } + +// IsPrivate tells whether the namespace of type t is configured as private +// (i.e. it exists and is not shared). +func (n Namespaces) IsPrivate(t NamespaceType) bool { + for _, v := range n { + if v.Type == t { + return v.Path == "" + } + } + // Not found, so implicitly sharing a parent namespace. + return false +} diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 73264bc90..59262d3ab 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -549,7 +549,6 @@ func (c *Container) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, l nsMaps[ns.Type] = ns.Path } } - _, sharePidns := nsMaps[configs.NEWPID] data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps, initStandard) if err != nil { return nil, err @@ -594,7 +593,7 @@ func (c *Container) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, l container: c, process: p, bootstrapData: data, - sharePidns: sharePidns, + sharePidns: !c.config.Namespaces.IsPrivate(configs.NEWPID), } c.initProcess = init return init, nil diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 376dd0f1f..4ac0f466b 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -1355,16 +1355,26 @@ func TestPIDHost(t *testing.T) { } } -func TestPIDHostInitProcessWait(t *testing.T) { +func TestHostPidnsInitKill(t *testing.T) { + config := newTemplateConfig(t, nil) + // Implicitly use host pid ns. + config.Namespaces.Remove(configs.NEWPID) + testPidnsInitKill(t, config) +} + +func TestSharedPidnsInitKill(t *testing.T) { + config := newTemplateConfig(t, nil) + // Explicitly use host pid ns. + config.Namespaces.Add(configs.NEWPID, "/proc/1/ns/pid") + testPidnsInitKill(t, config) +} + +func testPidnsInitKill(t *testing.T, config *configs.Config) { if testing.Short() { return } - pidns := "/proc/1/ns/pid" - // Run a container with two long-running processes. - config := newTemplateConfig(t, nil) - config.Namespaces.Add(configs.NEWPID, pidns) container, err := newContainer(t, config) ok(t, err) defer func() {