@@ -29,10 +29,6 @@ import (
2929
3030const stdioFdCount = 3
3131
32- // InitContinueSignal is used to signal the container init process to
33- // start the users specified process after the container create has finished.
34- const InitContinueSignal = syscall .SIGCONT
35-
3632type linuxContainer struct {
3733 id string
3834 root string
@@ -195,16 +191,39 @@ func (c *linuxContainer) Run(process *Process) error {
195191 if err != nil {
196192 return err
197193 }
198- isInit := status == Stopped
199- if err := c .start (process , isInit ); err != nil {
194+ if err := c .start (process , status == Stopped ); err != nil {
200195 return err
201196 }
202- if isInit {
203- return process . ops . signal ( InitContinueSignal )
197+ if status == Stopped {
198+ return c . exec ( )
204199 }
205200 return nil
206201}
207202
203+ func (c * linuxContainer ) Exec () error {
204+ c .m .Lock ()
205+ defer c .m .Unlock ()
206+ return c .exec ()
207+ }
208+
209+ func (c * linuxContainer ) exec () error {
210+ path := filepath .Join (c .root , execFifoFilename )
211+ f , err := os .OpenFile (path , os .O_RDONLY , 0 )
212+ if err != nil {
213+ return newSystemErrorWithCause (err , "open exec fifo for reading" )
214+ }
215+ defer f .Close ()
216+ data , err := ioutil .ReadAll (f )
217+ if err != nil {
218+ return err
219+ }
220+ if len (data ) > 0 {
221+ os .Remove (path )
222+ return nil
223+ }
224+ return fmt .Errorf ("cannot start an already running container" )
225+ }
226+
208227func (c * linuxContainer ) start (process * Process , isInit bool ) error {
209228 parent , err := c .newParentProcess (process , isInit )
210229 if err != nil {
@@ -262,17 +281,21 @@ func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProces
262281 if err != nil {
263282 return nil , newSystemErrorWithCause (err , "creating new init pipe" )
264283 }
265- cmd , err := c .commandTemplate (p , childPipe )
284+ rootDir , err := os .Open (c .root )
285+ if err != nil {
286+ return nil , err
287+ }
288+ cmd , err := c .commandTemplate (p , childPipe , rootDir )
266289 if err != nil {
267290 return nil , newSystemErrorWithCause (err , "creating new command template" )
268291 }
269292 if ! doInit {
270- return c .newSetnsProcess (p , cmd , parentPipe , childPipe )
293+ return c .newSetnsProcess (p , cmd , parentPipe , childPipe , rootDir )
271294 }
272- return c .newInitProcess (p , cmd , parentPipe , childPipe )
295+ return c .newInitProcess (p , cmd , parentPipe , childPipe , rootDir )
273296}
274297
275- func (c * linuxContainer ) commandTemplate (p * Process , childPipe * os.File ) (* exec.Cmd , error ) {
298+ func (c * linuxContainer ) commandTemplate (p * Process , childPipe , rootDir * os.File ) (* exec.Cmd , error ) {
276299 cmd := & exec.Cmd {
277300 Path : c .initPath ,
278301 Args : c .initArgs ,
@@ -284,8 +307,10 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
284307 if cmd .SysProcAttr == nil {
285308 cmd .SysProcAttr = & syscall.SysProcAttr {}
286309 }
287- cmd .ExtraFiles = append (p .ExtraFiles , childPipe )
288- cmd .Env = append (cmd .Env , fmt .Sprintf ("_LIBCONTAINER_INITPIPE=%d" , stdioFdCount + len (cmd .ExtraFiles )- 1 ))
310+ cmd .ExtraFiles = append (p .ExtraFiles , childPipe , rootDir )
311+ cmd .Env = append (cmd .Env ,
312+ fmt .Sprintf ("_LIBCONTAINER_INITPIPE=%d" , stdioFdCount + len (cmd .ExtraFiles )- 2 ),
313+ fmt .Sprintf ("_LIBCONTAINER_STATEDIR=%d" , stdioFdCount + len (cmd .ExtraFiles )- 1 ))
289314 // NOTE: when running a container with no PID namespace and the parent process spawning the container is
290315 // PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason
291316 // even with the parent still running.
@@ -295,7 +320,7 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
295320 return cmd , nil
296321}
297322
298- func (c * linuxContainer ) newInitProcess (p * Process , cmd * exec.Cmd , parentPipe , childPipe * os.File ) (* initProcess , error ) {
323+ func (c * linuxContainer ) newInitProcess (p * Process , cmd * exec.Cmd , parentPipe , childPipe , rootDir * os.File ) (* initProcess , error ) {
299324 cmd .Env = append (cmd .Env , "_LIBCONTAINER_INITTYPE=" + string (initStandard ))
300325 nsMaps := make (map [configs.NamespaceType ]string )
301326 for _ , ns := range c .config .Namespaces {
@@ -318,10 +343,11 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, c
318343 process : p ,
319344 bootstrapData : data ,
320345 sharePidns : sharePidns ,
346+ rootDir : rootDir ,
321347 }, nil
322348}
323349
324- func (c * linuxContainer ) newSetnsProcess (p * Process , cmd * exec.Cmd , parentPipe , childPipe * os.File ) (* setnsProcess , error ) {
350+ func (c * linuxContainer ) newSetnsProcess (p * Process , cmd * exec.Cmd , parentPipe , childPipe , rootDir * os.File ) (* setnsProcess , error ) {
325351 cmd .Env = append (cmd .Env , "_LIBCONTAINER_INITTYPE=" + string (initSetns ))
326352 state , err := c .currentState ()
327353 if err != nil {
@@ -342,6 +368,7 @@ func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe,
342368 config : c .newInitConfig (p ),
343369 process : p ,
344370 bootstrapData : data ,
371+ rootDir : rootDir ,
345372 }, nil
346373}
347374
@@ -360,6 +387,7 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
360387 AppArmorProfile : c .config .AppArmorProfile ,
361388 ProcessLabel : c .config .ProcessLabel ,
362389 Rlimits : c .config .Rlimits ,
390+ ExecFifoPath : filepath .Join (c .root , execFifoFilename ),
363391 }
364392 if process .NoNewPrivileges != nil {
365393 cfg .NoNewPrivileges = * process .NoNewPrivileges
0 commit comments