From 805b8c73d38baa27ca6e43b4ccab722f8bc2257e Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Wed, 22 Feb 2017 10:34:48 -0800 Subject: [PATCH 1/2] Do not create exec fifo in factory.Create It should not be binded to container creation, for example, runc restore needs to create a libcontainer.Container, but it won't need exec fifo. So create exec fifo when container is started or run, where we really need it. Signed-off-by: Qiang Huang --- libcontainer/container_linux.go | 49 +++++++++++++++++++++++++++++++-- libcontainer/factory_linux.go | 10 ------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 9f0043fb0..6b65accf6 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -191,17 +191,29 @@ func (c *linuxContainer) Start(process *Process) error { if err != nil { return err } - return c.start(process, status == Stopped) + if status == Stopped { + if err := c.createExecFifo(); err != nil { + return err + } + } + if err := c.start(process, status == Stopped); err != nil { + if status == Stopped { + c.deleteExecFifo() + } + return err + } + return nil } func (c *linuxContainer) Run(process *Process) error { c.m.Lock() - defer c.m.Unlock() status, err := c.currentStatus() if err != nil { + c.m.Unlock() return err } - if err := c.start(process, status == Stopped); err != nil { + c.m.Unlock() + if err := c.Start(process); err != nil { return err } if status == Stopped { @@ -291,6 +303,37 @@ func (c *linuxContainer) Signal(s os.Signal, all bool) error { return nil } +func (c *linuxContainer) createExecFifo() error { + rootuid, err := c.Config().HostUID() + if err != nil { + return err + } + rootgid, err := c.Config().HostGID() + if err != nil { + return err + } + + fifoName := filepath.Join(c.root, execFifoFilename) + if _, err := os.Stat(fifoName); err == nil { + return fmt.Errorf("exec fifo %s already exists", fifoName) + } + oldMask := syscall.Umask(0000) + if err := syscall.Mkfifo(fifoName, 0622); err != nil { + syscall.Umask(oldMask) + return err + } + syscall.Umask(oldMask) + if err := os.Chown(fifoName, rootuid, rootgid); err != nil { + return err + } + return nil +} + +func (c *linuxContainer) deleteExecFifo() { + fifoName := filepath.Join(c.root, execFifoFilename) + os.Remove(fifoName) +} + func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProcess, error) { parentPipe, childPipe, err := newPipe() if err != nil { diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go index 162355013..7f044bd45 100644 --- a/libcontainer/factory_linux.go +++ b/libcontainer/factory_linux.go @@ -169,16 +169,6 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err if err := os.Chown(containerRoot, uid, gid); err != nil { return nil, newGenericError(err, SystemError) } - fifoName := filepath.Join(containerRoot, execFifoFilename) - oldMask := syscall.Umask(0000) - if err := syscall.Mkfifo(fifoName, 0622); err != nil { - syscall.Umask(oldMask) - return nil, newGenericError(err, SystemError) - } - syscall.Umask(oldMask) - if err := os.Chown(fifoName, uid, gid); err != nil { - return nil, newGenericError(err, SystemError) - } c := &linuxContainer{ id: id, root: containerRoot, From 733563552e637e5b1d9d45548b89ab44f484609b Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Tue, 21 Feb 2017 18:16:19 -0800 Subject: [PATCH 2/2] Fix state when _LIBCONTAINER in environment Fixes: #1311 Signed-off-by: Qiang Huang --- libcontainer/container_linux.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 6b65accf6..213bab464 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -1259,14 +1259,9 @@ func (c *linuxContainer) runType() (Status, error) { if !exist || err != nil { return Stopped, err } - // check if the process that is running is the init process or the user's process. - // this is the difference between the container Running and Created. - environ, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/environ", pid)) - if err != nil { - return Stopped, newSystemErrorWithCausef(err, "reading /proc/%d/environ", pid) - } - check := []byte("_LIBCONTAINER") - if bytes.Contains(environ, check) { + // We'll create exec fifo and blocking on it after container is created, + // and delete it after start container. + if _, err := os.Stat(filepath.Join(c.root, execFifoFilename)); err == nil { return Created, nil } return Running, nil