@@ -22,6 +22,7 @@ import (
2222 "github.com/opencontainers/runc/libcontainer/cgroups"
2323 "github.com/opencontainers/runc/libcontainer/configs"
2424 "github.com/opencontainers/runc/libcontainer/criurpc"
25+ "github.com/opencontainers/runc/libcontainer/system"
2526 "github.com/opencontainers/runc/libcontainer/utils"
2627 "github.com/syndtr/gocapability/capability"
2728 "github.com/vishvananda/netlink/nl"
@@ -30,18 +31,19 @@ import (
3031const stdioFdCount = 3
3132
3233type linuxContainer struct {
33- id string
34- root string
35- config * configs.Config
36- cgroupManager cgroups.Manager
37- initPath string
38- initArgs []string
39- initProcess parentProcess
40- criuPath string
41- m sync.Mutex
42- criuVersion int
43- state containerState
44- created time.Time
34+ id string
35+ root string
36+ config * configs.Config
37+ cgroupManager cgroups.Manager
38+ initPath string
39+ initArgs []string
40+ initProcess parentProcess
41+ initProcessStartTime string
42+ criuPath string
43+ m sync.Mutex
44+ criuVersion int
45+ state containerState
46+ created time.Time
4547}
4648
4749// State represents a running container's state
@@ -252,9 +254,12 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
252254 c .state = & createdState {
253255 c : c ,
254256 }
255- if err := c .updateState (parent ); err != nil {
257+ state , err := c .updateState (parent )
258+ if err != nil {
256259 return err
257260 }
261+ c .initProcessStartTime = state .InitProcessStartTime
262+
258263 if c .config .Hooks != nil {
259264 s := configs.HookState {
260265 Version : c .config .Version ,
@@ -1043,7 +1048,7 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
10431048 }); err != nil {
10441049 return err
10451050 }
1046- if err := c .updateState (r ); err != nil {
1051+ if _ , err := c .updateState (r ); err != nil {
10471052 return err
10481053 }
10491054 if err := os .Remove (filepath .Join (c .root , "checkpoint" )); err != nil {
@@ -1055,13 +1060,17 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
10551060 return nil
10561061}
10571062
1058- func (c * linuxContainer ) updateState (process parentProcess ) error {
1063+ func (c * linuxContainer ) updateState (process parentProcess ) ( * State , error ) {
10591064 c .initProcess = process
10601065 state , err := c .currentState ()
10611066 if err != nil {
1062- return err
1067+ return nil , err
1068+ }
1069+ err = c .saveState (state )
1070+ if err != nil {
1071+ return nil , err
10631072 }
1064- return c . saveState ( state )
1073+ return state , nil
10651074}
10661075
10671076func (c * linuxContainer ) saveState (s * State ) error {
@@ -1109,6 +1118,21 @@ func (c *linuxContainer) refreshState() error {
11091118 return c .state .transition (& stoppedState {c : c })
11101119}
11111120
1121+ // doesInitProcessExist checks if the init process is still the same process
1122+ // as the initial one, it could happen that the original process has exited
1123+ // and a new process has been created with the same pid, in this case, the
1124+ // container would already be stopped.
1125+ func (c * linuxContainer ) doesInitProcessExist (initPid int ) (bool , error ) {
1126+ startTime , err := system .GetProcessStartTime (initPid )
1127+ if err != nil {
1128+ return false , newSystemErrorWithCausef (err , "getting init process %d start time" , initPid )
1129+ }
1130+ if c .initProcessStartTime != startTime {
1131+ return false , nil
1132+ }
1133+ return true , nil
1134+ }
1135+
11121136func (c * linuxContainer ) runType () (Status , error ) {
11131137 if c .initProcess == nil {
11141138 return Stopped , nil
@@ -1124,6 +1148,11 @@ func (c *linuxContainer) runType() (Status, error) {
11241148 }
11251149 return Stopped , newSystemErrorWithCausef (err , "sending signal 0 to pid %d" , pid )
11261150 }
1151+ // check if the process is still the original init process.
1152+ exist , err := c .doesInitProcessExist (pid )
1153+ if ! exist || err != nil {
1154+ return Stopped , err
1155+ }
11271156 // check if the process that is running is the init process or the user's process.
11281157 // this is the difference between the container Running and Created.
11291158 environ , err := ioutil .ReadFile (fmt .Sprintf ("/proc/%d/environ" , pid ))
0 commit comments