diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 616cd1ede..d0faaa47e 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -115,7 +115,7 @@ func (c *Container) ignoreCgroupError(err error) error { if err == nil { return nil } - if errors.Is(err, os.ErrNotExist) && c.runType() == Stopped && !c.cgroupManager.Exists() { + if errors.Is(err, os.ErrNotExist) && !c.hasInit() && !c.cgroupManager.Exists() { return nil } return err @@ -1006,34 +1006,31 @@ func (c *Container) refreshState() error { if paused { return c.state.transition(&pausedState{c: c}) } - t := c.runType() - switch t { - case Created: - return c.state.transition(&createdState{c: c}) - case Running: - return c.state.transition(&runningState{c: c}) + if !c.hasInit() { + return c.state.transition(&stoppedState{c: c}) } - return c.state.transition(&stoppedState{c: c}) + // The presence of exec fifo helps to distinguish between + // the created and the running states. + if _, err := os.Stat(filepath.Join(c.stateDir, execFifoFilename)); err == nil { + return c.state.transition(&createdState{c: c}) + } + return c.state.transition(&runningState{c: c}) } -func (c *Container) runType() Status { +// hasInit tells whether the container init process exists. +func (c *Container) hasInit() bool { if c.initProcess == nil { - return Stopped + return false } pid := c.initProcess.pid() stat, err := system.Stat(pid) if err != nil { - return Stopped + return false } if stat.StartTime != c.initProcessStartTime || stat.State == system.Zombie || stat.State == system.Dead { - return Stopped + return false } - // 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.stateDir, execFifoFilename)); err == nil { - return Created - } - return Running + return true } func (c *Container) isPaused() (bool, error) { diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go index c6967e5f4..0f629922b 100644 --- a/libcontainer/state_linux.go +++ b/libcontainer/state_linux.go @@ -103,7 +103,7 @@ func (r *runningState) status() Status { func (r *runningState) transition(s containerState) error { switch s.(type) { case *stoppedState: - if r.c.runType() == Running { + if r.c.hasInit() { return ErrRunning } r.c.state = s @@ -118,7 +118,7 @@ func (r *runningState) transition(s containerState) error { } func (r *runningState) destroy() error { - if r.c.runType() == Running { + if r.c.hasInit() { return ErrRunning } return destroy(r.c) @@ -170,14 +170,13 @@ func (p *pausedState) transition(s containerState) error { } func (p *pausedState) destroy() error { - t := p.c.runType() - if t != Running && t != Created { - if err := p.c.cgroupManager.Freeze(configs.Thawed); err != nil { - return err - } - return destroy(p.c) + if p.c.hasInit() { + return ErrPaused } - return ErrPaused + if err := p.c.cgroupManager.Freeze(configs.Thawed); err != nil { + return err + } + return destroy(p.c) } // restoredState is the same as the running state but also has associated checkpoint