We can't keep file descriptors without close-on-exec except with syscall.ForkLock held, as otherwise they could leak by accident into other children from forks in other threads. Instead we just use Cmd.ExtraFiles which handles all this for us. This fixes https://github.com/dotcloud/docker/issues/4493 Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson) Upstream-commit: 5c9b28db1853cccdf7a1037eeaad372d12cd68fa Component: engine
46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
package nsinit
|
|
|
|
import (
|
|
"github.com/dotcloud/docker/pkg/libcontainer"
|
|
"github.com/dotcloud/docker/pkg/system"
|
|
"os"
|
|
"os/exec"
|
|
)
|
|
|
|
// CommandFactory takes the container's configuration and options passed by the
|
|
// parent processes and creates an *exec.Cmd that will be used to fork/exec the
|
|
// namespaced init process
|
|
type CommandFactory interface {
|
|
Create(container *libcontainer.Container, console string, syncFd *os.File, args []string) *exec.Cmd
|
|
}
|
|
|
|
type DefaultCommandFactory struct {
|
|
Root string
|
|
}
|
|
|
|
// Create will return an exec.Cmd with the Cloneflags set to the proper namespaces
|
|
// defined on the container's configuration and use the current binary as the init with the
|
|
// args provided
|
|
func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe *os.File, args []string) *exec.Cmd {
|
|
// get our binary name from arg0 so we can always reexec ourself
|
|
command := exec.Command(os.Args[0], append([]string{
|
|
"-console", console,
|
|
"-pipe", "3",
|
|
"-root", c.Root,
|
|
"init"}, args...)...)
|
|
|
|
system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
|
|
command.Env = container.Env
|
|
command.ExtraFiles = []*os.File{pipe}
|
|
return command
|
|
}
|
|
|
|
// GetNamespaceFlags parses the container's Namespaces options to set the correct
|
|
// flags on clone, unshare, and setns
|
|
func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
|
|
for _, ns := range namespaces {
|
|
flag |= ns.Value
|
|
}
|
|
return flag
|
|
}
|