Move childPipe to the end of FD set

This adds a new env var for identifying the internal sync pipe that
libcontainer uses to sync with the container and parent process.  This
replaces #496 to allow the user to add additional files to the processes
and not take over fd 3 for all containers.

Closes #496

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2015-04-08 14:14:51 -07:00
parent 708b25e61e
commit 570eed473b
6 changed files with 16 additions and 24 deletions

View File

@ -16,6 +16,8 @@ import (
"github.com/docker/libcontainer/configs"
)
const stdioFdCount = 3
type linuxContainer struct {
id string
root string
@ -139,7 +141,8 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
cmd.ExtraFiles = append([]*os.File{childPipe}, p.ExtraFiles...)
cmd.ExtraFiles = append(p.ExtraFiles, childPipe)
cmd.Env = append(cmd.Env, fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1))
// 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.
@ -178,11 +181,9 @@ func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe,
fmt.Sprintf("_LIBCONTAINER_INITPID=%d", c.initProcess.pid()),
"_LIBCONTAINER_INITTYPE=setns",
)
if p.consolePath != "" {
cmd.Env = append(cmd.Env, "_LIBCONTAINER_CONSOLE_PATH="+p.consolePath)
}
// TODO: set on container for process management
return &setnsProcess{
cmd: cmd,

View File

@ -33,14 +33,12 @@ type Factory interface {
Load(id string) (Container, error)
// StartInitialization is an internal API to libcontainer used during the rexec of the
// container. pipefd is the fd to the child end of the pipe used to syncronize the
// parent and child process providing state and configuration to the child process and
// returning any errors during the init of the container
// container.
//
// Errors:
// pipe connection error
// system error
StartInitialization(pipefd uintptr) error
// Pipe connection error
// System error
StartInitialization() error
// Type returns info string about factory type (e.g. lxc, libcontainer...)
Type() string

View File

@ -10,6 +10,7 @@ import (
"os/exec"
"path/filepath"
"regexp"
"strconv"
"syscall"
"github.com/docker/docker/pkg/mount"
@ -194,7 +195,11 @@ func (l *LinuxFactory) Type() string {
// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state
// This is a low level implementation detail of the reexec and should not be consumed externally
func (l *LinuxFactory) StartInitialization(pipefd uintptr) (err error) {
func (l *LinuxFactory) StartInitialization() (err error) {
pipefd, err := strconv.Atoi(os.Getenv("_LIBCONTAINER_INITPIPE"))
if err != nil {
return err
}
var (
pipe = os.NewFile(uintptr(pipefd), "pipe")
it = initType(os.Getenv("_LIBCONTAINER_INITTYPE"))

View File

@ -96,21 +96,9 @@ func populateProcessEnvironment(env []string) error {
// and working dir, and closes any leaked file descriptors
// before executing the command inside the namespace
func finalizeNamespace(config *initConfig) error {
// FD 3 is the child pipe, which needs to be closed.
// Additional file descriptors starts from 3 to (3 + n)
// To fix the order all additional file descriptors
// are shiftet by one right
for fd := 3; fd < (config.PassedFilesCount + 3); fd++ {
err := syscall.Dup2(fd+1, fd)
if err != nil {
return err
}
}
// Ensure that all unwanted fds we may have accidentally
// inherited are marked close-on-exec so they stay out of the
// container
if err := utils.CloseExecFrom(config.PassedFilesCount + 3); err != nil {
return err
}

View File

@ -21,7 +21,7 @@ func init() {
if err != nil {
log.Fatalf("unable to initialize for container: %s", err)
}
if err := factory.StartInitialization(3); err != nil {
if err := factory.StartInitialization(); err != nil {
log.Fatal(err)
}
}

View File

@ -20,7 +20,7 @@ var initCommand = cli.Command{
if err != nil {
fatal(err)
}
if err := factory.StartInitialization(3); err != nil {
if err := factory.StartInitialization(); err != nil {
fatal(err)
}
panic("This line should never been executed")