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 <dqminh89@gmail.com>
This commit is contained in:
Daniel, Dao Quang Minh 2015-10-17 15:14:26 +00:00
parent 97bc9a7faf
commit d914bf7347
2 changed files with 21 additions and 15 deletions

View File

@ -218,7 +218,7 @@ func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProces
return nil, newSystemError(err) return nil, newSystemError(err)
} }
if !doInit { if !doInit {
return c.newSetnsProcess(p, cmd, parentPipe, childPipe), nil return c.newSetnsProcess(p, cmd, parentPipe, childPipe)
} }
return c.newInitProcess(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 }, 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, cmd.Env = append(cmd.Env,
fmt.Sprintf("_LIBCONTAINER_INITPID=%d", c.initProcess.pid()), fmt.Sprintf("_LIBCONTAINER_INITPID=%d", c.initProcess.pid()),
"_LIBCONTAINER_INITTYPE=setns", "_LIBCONTAINER_INITTYPE=setns",
@ -289,7 +289,7 @@ func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe,
parentPipe: parentPipe, parentPipe: parentPipe,
config: c.newInitConfig(p), config: c.newInitConfig(p),
process: p, process: p,
} }, nil
} }
func (c *linuxContainer) newInitConfig(process *Process) *initConfig { func (c *linuxContainer) newInitConfig(process *Process) *initConfig {

View File

@ -41,13 +41,14 @@ type parentProcess interface {
} }
type setnsProcess struct { type setnsProcess struct {
cmd *exec.Cmd cmd *exec.Cmd
parentPipe *os.File parentPipe *os.File
childPipe *os.File childPipe *os.File
cgroupPaths map[string]string cgroupPaths map[string]string
config *initConfig config *initConfig
fds []string fds []string
process *Process process *Process
bootstrapData io.Reader
} }
func (p *setnsProcess) startTime() (string, error) { func (p *setnsProcess) startTime() (string, error) {
@ -64,6 +65,16 @@ func (p *setnsProcess) signal(sig os.Signal) error {
func (p *setnsProcess) start() (err error) { func (p *setnsProcess) start() (err error) {
defer p.parentPipe.Close() 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 { if err = p.execSetns(); err != nil {
return newSystemError(err) 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 // before the go runtime boots, we wait on the process to die and receive the child's pid
// over the provided pipe. // over the provided pipe.
func (p *setnsProcess) execSetns() error { func (p *setnsProcess) execSetns() error {
err := p.cmd.Start()
p.childPipe.Close()
if err != nil {
return newSystemError(err)
}
status, err := p.cmd.Process.Wait() status, err := p.cmd.Process.Wait()
if err != nil { if err != nil {
p.cmd.Wait() p.cmd.Wait()