diff --git a/libcontainer/container.go b/libcontainer/container.go index c4aa99ecf5f..1d1bbf5eae2 100644 --- a/libcontainer/container.go +++ b/libcontainer/container.go @@ -22,6 +22,8 @@ const ( Paused // Stopped is the status that denotes the container does not have a created or running process. Stopped + // Creating is the status that denotes the container is creating. + Creating ) func (s Status) String() string { @@ -34,6 +36,8 @@ func (s Status) String() string { return "paused" case Stopped: return "stopped" + case Creating: + return "creating" default: return "unknown" } diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 2dc2b86eb41..60695c28b03 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -628,7 +628,6 @@ func (c *Container) newInitProcess(p *Process, cmd *exec.Cmd, comm *processComm) }, intelRdtManager: c.intelRdtManager, } - c.initProcess = init return init, nil } @@ -883,6 +882,9 @@ func (c *Container) currentStatus() (Status, error) { // out of process we need to verify the container's status based on runtime // information and not rely on our in process info. func (c *Container) refreshState() error { + if c.hasInit() && c.initProcess.pid() == -1 { + return c.state.transition(&creatingState{c: c}) + } paused, err := c.isPaused() if err != nil { return err diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index 88861f0a94d..6a1063ed099 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -554,6 +554,13 @@ func (p *initProcess) start() (retErr error) { return fmt.Errorf("unable to start init: %w", err) } + // SIGKILL may happen at any time, so generate state.json here + _, err = p.container.updateState(nil) + if err != nil { + return fmt.Errorf("unable to store init state before creating cgroup: %w", err) + } + p.container.initProcess = p + defer func() { if retErr != nil { // Find out if init is killed by the kernel's OOM killer. diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go index 2b7b8b5bc36..142fbd5bc26 100644 --- a/libcontainer/state_linux.go +++ b/libcontainer/state_linux.go @@ -242,3 +242,20 @@ func (n *loadedState) destroy() error { } return n.c.state.destroy() } + +type creatingState struct { + c *Container +} + +func (i *creatingState) status() Status { + return Creating +} + +func (i *creatingState) transition(s containerState) error { + return newStateTransitionError(i, s) +} + +func (i *creatingState) destroy() error { + _ = signalAllProcesses(i.c.cgroupManager, unix.SIGKILL) + return destroy(i.c) +}