Skip to content

Commit

Permalink
Make state detection procise
Browse files Browse the repository at this point in the history
Fixes: #871

Signed-off-by: Qiang Huang <[email protected]>
  • Loading branch information
hqhq committed Jun 30, 2016
1 parent 629e356 commit ef15ae4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 26 deletions.
53 changes: 36 additions & 17 deletions libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/criurpc"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/syndtr/gocapability/capability"
"github.com/vishvananda/netlink/nl"
Expand All @@ -30,18 +31,19 @@ import (
const stdioFdCount = 3

type linuxContainer struct {
id string
root string
config *configs.Config
cgroupManager cgroups.Manager
initPath string
initArgs []string
initProcess parentProcess
criuPath string
m sync.Mutex
criuVersion int
state containerState
created time.Time
id string
root string
config *configs.Config
cgroupManager cgroups.Manager
initPath string
initArgs []string
initProcess parentProcess
initProcessStartTime string
criuPath string
m sync.Mutex
criuVersion int
state containerState
created time.Time
}

// State represents a running container's state
Expand Down Expand Up @@ -252,9 +254,12 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
c.state = &createdState{
c: c,
}
if err := c.updateState(parent); err != nil {
state, err := c.updateState(parent)
if err != nil {
return err
}
c.initProcessStartTime = state.InitProcessStartTime

if c.config.Hooks != nil {
s := configs.HookState{
Version: c.config.Version,
Expand Down Expand Up @@ -1043,7 +1048,7 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
}); err != nil {
return err
}
if err := c.updateState(r); err != nil {
if _, err := c.updateState(r); err != nil {
return err
}
if err := os.Remove(filepath.Join(c.root, "checkpoint")); err != nil {
Expand All @@ -1055,13 +1060,17 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
return nil
}

func (c *linuxContainer) updateState(process parentProcess) error {
func (c *linuxContainer) updateState(process parentProcess) (*State, error) {
c.initProcess = process
state, err := c.currentState()
if err != nil {
return err
return nil, err
}
err = c.saveState(state)
if err != nil {
return nil, err
}
return c.saveState(state)
return state, nil
}

func (c *linuxContainer) saveState(s *State) error {
Expand Down Expand Up @@ -1124,6 +1133,16 @@ func (c *linuxContainer) runType() (Status, error) {
}
return Stopped, newSystemErrorWithCausef(err, "sending signal 0 to pid %d", pid)
}
// check if the init process is still the same process as the initial one,
// it could happen that the process is exited and a new process created with
// the same pid, in this case, the container would already be stopped.
startTime, err := system.GetProcessStartTime(pid)
if err != nil {
return Stopped, newSystemErrorWithCausef(err, "getting init process %d start time", pid)
}
if c.initProcessStartTime != startTime {
return Stopped, nil
}
// check if the process that is running is the init process or the user's process.
// this is the difference between the container Running and Created.
environ, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/environ", pid))
Expand Down
19 changes: 10 additions & 9 deletions libcontainer/factory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,16 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
fds: state.ExternalDescriptors,
}
c := &linuxContainer{
initProcess: r,
id: id,
config: &state.Config,
initPath: l.InitPath,
initArgs: l.InitArgs,
criuPath: l.CriuPath,
cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
root: containerRoot,
created: state.Created,
initProcess: r,
initProcessStartTime: state.InitProcessStartTime,
id: id,
config: &state.Config,
initPath: l.InitPath,
initArgs: l.InitArgs,
criuPath: l.CriuPath,
cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
root: containerRoot,
created: state.Created,
}
c.state = &loadedState{c: c}
if err := c.refreshState(); err != nil {
Expand Down

0 comments on commit ef15ae4

Please sign in to comment.