From d914bf73473868501bb744023c76be798cb6461d Mon Sep 17 00:00:00 2001 From: "Daniel, Dao Quang Minh" Date: Sat, 17 Oct 2015 15:14:26 +0000 Subject: [PATCH] setns: add bootstrap data add bootstrap data to setns process. If we have any bootstrap data then copy it to the bootstrap process (i.e. nsexec) using the sync pipe. This will allow us to eventually replace environment variable usage with more structured data to setup namespaces, write pid/gid map, setgroup etc. Signed-off-by: Daniel, Dao Quang Minh --- libcontainer/container_linux.go | 6 +++--- libcontainer/process_linux.go | 30 ++++++++++++++++++------------ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 912673a3..0b7fdeb3 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -218,7 +218,7 @@ func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProces return nil, newSystemError(err) } if !doInit { - return c.newSetnsProcess(p, cmd, parentPipe, childPipe), nil + return c.newSetnsProcess(p, cmd, parentPipe, childPipe) } return c.newInitProcess(p, cmd, parentPipe, childPipe) } @@ -273,7 +273,7 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, c }, nil } -func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) *setnsProcess { +func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) (*setnsProcess, error) { cmd.Env = append(cmd.Env, fmt.Sprintf("_LIBCONTAINER_INITPID=%d", c.initProcess.pid()), "_LIBCONTAINER_INITTYPE=setns", @@ -289,7 +289,7 @@ func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe, parentPipe: parentPipe, config: c.newInitConfig(p), process: p, - } + }, nil } func (c *linuxContainer) newInitConfig(process *Process) *initConfig { diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index 4d17cbc5..f27b6cf4 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -41,13 +41,14 @@ type parentProcess interface { } type setnsProcess struct { - cmd *exec.Cmd - parentPipe *os.File - childPipe *os.File - cgroupPaths map[string]string - config *initConfig - fds []string - process *Process + cmd *exec.Cmd + parentPipe *os.File + childPipe *os.File + cgroupPaths map[string]string + config *initConfig + fds []string + process *Process + bootstrapData io.Reader } func (p *setnsProcess) startTime() (string, error) { @@ -64,6 +65,16 @@ func (p *setnsProcess) signal(sig os.Signal) error { func (p *setnsProcess) start() (err error) { defer p.parentPipe.Close() + err = p.cmd.Start() + p.childPipe.Close() + if err != nil { + return newSystemError(err) + } + if p.bootstrapData != nil { + if _, err := io.Copy(p.parentPipe, p.bootstrapData); err != nil { + return newSystemError(err) + } + } if err = p.execSetns(); err != nil { return newSystemError(err) } @@ -96,11 +107,6 @@ func (p *setnsProcess) start() (err error) { // before the go runtime boots, we wait on the process to die and receive the child's pid // over the provided pipe. func (p *setnsProcess) execSetns() error { - err := p.cmd.Start() - p.childPipe.Close() - if err != nil { - return newSystemError(err) - } status, err := p.cmd.Process.Wait() if err != nil { p.cmd.Wait()