execution/oci: Add check when loading processes
This should ensure that we don't kill a different process after a restore (once supported) Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
parent
abaa421141
commit
73cb78fae3
2 changed files with 42 additions and 23 deletions
|
@ -16,6 +16,11 @@ const (
|
||||||
initProcessID = "init"
|
initProcessID = "init"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PidFilename = "pid"
|
||||||
|
StartTimeFilename = "starttime"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string")
|
ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string")
|
||||||
)
|
)
|
||||||
|
@ -64,7 +69,7 @@ func (r *OCIRuntime) Create(ctx context.Context, id string, o execution.CreateOp
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pidFile := filepath.Join(initStateDir, "pid")
|
pidFile := filepath.Join(initStateDir, PidFilename)
|
||||||
err = r.runc.Create(ctx, id, o.Bundle, &runc.CreateOpts{
|
err = r.runc.Create(ctx, id, o.Bundle, &runc.CreateOpts{
|
||||||
PidFile: pidFile,
|
PidFile: pidFile,
|
||||||
Console: oio.console,
|
Console: oio.console,
|
||||||
|
@ -80,11 +85,7 @@ func (r *OCIRuntime) Create(ctx context.Context, id string, o execution.CreateOp
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pid, err := runc.ReadPidFile(pidFile)
|
process, err := newProcess(container, initProcessID, initStateDir)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
process, err := newProcess(container, initProcessID, pid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -122,19 +123,11 @@ func (r *OCIRuntime) load(runcC *runc.Container) (*execution.Container, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, d := range dirs {
|
for _, d := range dirs {
|
||||||
pid, err := runc.ReadPidFile(filepath.Join(d, "pid"))
|
process, err := newProcess(container, filepath.Base(d), d)
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
// Process died in between
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
process, err := newProcess(container, filepath.Base(d), pid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
container.AddProcess(process, pid == runcC.Pid)
|
container.AddProcess(process, process.Pid() == int64(runcC.Pid))
|
||||||
}
|
}
|
||||||
|
|
||||||
return container, nil
|
return container, nil
|
||||||
|
@ -212,7 +205,7 @@ func (r *OCIRuntime) StartProcess(ctx context.Context, c *execution.Container, o
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pidFile := filepath.Join(procStateDir, "pid")
|
pidFile := filepath.Join(procStateDir, PidFilename)
|
||||||
if err := r.runc.Exec(ctx, c.ID(), o.Spec, &runc.ExecOpts{
|
if err := r.runc.Exec(ctx, c.ID(), o.Spec, &runc.ExecOpts{
|
||||||
PidFile: pidFile,
|
PidFile: pidFile,
|
||||||
Detach: false,
|
Detach: false,
|
||||||
|
@ -222,12 +215,8 @@ func (r *OCIRuntime) StartProcess(ctx context.Context, c *execution.Container, o
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pid, err := runc.ReadPidFile(pidFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
process, err := newProcess(c, o.ID, pid)
|
process, err := newProcess(c, o.ID, procStateDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,21 @@ package oci
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/crosbymichael/go-runc"
|
||||||
"github.com/docker/containerd/execution"
|
"github.com/docker/containerd/execution"
|
||||||
|
starttime "github.com/opencontainers/runc/libcontainer/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newProcess(c *execution.Container, id string, pid int) (execution.Process, error) {
|
func newProcess(c *execution.Container, id, stateDir string) (execution.Process, error) {
|
||||||
|
pid, err := runc.ReadPidFile(filepath.Join(stateDir, PidFilename))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
status := execution.Running
|
status := execution.Running
|
||||||
if err := syscall.Kill(pid, 0); err != nil {
|
if err := syscall.Kill(pid, 0); err != nil {
|
||||||
if err == syscall.ESRCH {
|
if err == syscall.ESRCH {
|
||||||
|
@ -17,6 +25,28 @@ func newProcess(c *execution.Container, id string, pid int) (execution.Process,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if status == execution.Running {
|
||||||
|
stime, err := starttime.GetProcessStartTime(pid)
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
status = execution.Stopped
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
default:
|
||||||
|
b, err := ioutil.ReadFile(filepath.Join(stateDir, StartTimeFilename))
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
err = ioutil.WriteFile(filepath.Join(stateDir, StartTimeFilename), []byte(stime), 0600)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
case string(b) != stime:
|
||||||
|
status = execution.Stopped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return &process{
|
return &process{
|
||||||
c: c,
|
c: c,
|
||||||
id: id,
|
id: id,
|
||||||
|
|
Loading…
Reference in a new issue