diff --git a/create.go b/create.go index 403dab8d4..096e8e335 100644 --- a/create.go +++ b/create.go @@ -46,6 +46,10 @@ command(s) that get executed on start, edit the args parameter of the spec. See Name: "no-new-keyring", Usage: "do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key", }, + cli.IntFlag{ + Name: "preserve-fds", + Usage: "Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)", + }, }, Action: func(context *cli.Context) error { if err := checkArgs(context, 1, exactArgs); err != nil { diff --git a/run.go b/run.go index 6a0a62292..ebec222ec 100644 --- a/run.go +++ b/run.go @@ -57,6 +57,10 @@ command(s) that get executed on start, edit the args parameter of the spec. See Name: "no-new-keyring", Usage: "do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key", }, + cli.IntFlag{ + Name: "preserve-fds", + Usage: "Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)", + }, }, Action: func(context *cli.Context) error { if err := checkArgs(context, 1, exactArgs); err != nil { diff --git a/utils_linux.go b/utils_linux.go index 867c2d7ad..9b831d5b5 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -180,6 +180,7 @@ type runner struct { shouldDestroy bool detach bool listenFDs []*os.File + preserveFDs int pidFile string consoleSocket string container libcontainer.Container @@ -196,11 +197,17 @@ func (r *runner) run(config *specs.Process) (int, error) { r.destroy() return -1, err } + if len(r.listenFDs) > 0 { process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(r.listenFDs)), "LISTEN_PID=1") process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...) } + baseFd := 3 + len(process.ExtraFiles) + for i := baseFd; i < baseFd+r.preserveFDs; i++ { + process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i))) + } + rootuid, err := r.container.Config().HostUID() if err != nil { r.destroy() @@ -353,6 +360,7 @@ func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, e consoleSocket: context.String("console-socket"), detach: context.Bool("detach"), pidFile: context.String("pid-file"), + preserveFDs: context.Int("preserve-fds"), create: create, } return r.run(&spec.Process)