Refactor process.go for platform specific

Signed-off-by: John Howard <jhoward@microsoft.com>

Move process sorter to new file

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Sort containers by id

This will not be the most accurate sorting but atleast the list will be
consistent inbetween calls.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Allow runtime to be configurable via daemon start

This allows people to pass an alternate name or location to the runtime
binary to start containers.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Fix state output for containers

Return the proper state/status for a container by checking if the pid is
still alive.  Also fix the cleanup handling in the shim to make sure
containers are not left behind.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Properly wait for container start

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
John Howard 2016-02-25 12:59:34 -08:00 committed by Michael Crosby
parent 0ad7654f80
commit b044ff0f29
19 changed files with 323 additions and 206 deletions

View file

@ -20,7 +20,7 @@ type StartTask struct {
func (s *Supervisor) start(t *StartTask) error {
start := time.Now()
container, err := runtime.New(s.stateDir, t.ID, t.BundlePath, t.Labels)
container, err := runtime.New(s.stateDir, t.ID, t.BundlePath, s.runtime, t.Labels)
if err != nil {
return err
}

View file

@ -17,9 +17,19 @@ func (s *Supervisor) exit(t *ExitTask) error {
proc := t.Process
status, err := proc.ExitStatus()
if err != nil {
logrus.WithField("error", err).Error("containerd: get exit status")
logrus.WithFields(logrus.Fields{
"error": err,
"pid": proc.ID(),
"id": proc.Container().ID(),
"systemPid": proc.SystemPid(),
}).Error("containerd: get exit status")
}
logrus.WithFields(logrus.Fields{"pid": proc.ID(), "status": status}).Debug("containerd: process exited")
logrus.WithFields(logrus.Fields{
"pid": proc.ID(),
"status": status,
"id": proc.Container().ID(),
"systemPid": proc.SystemPid(),
}).Debug("containerd: process exited")
// if the process is the the init process of the container then
// fire a separate event for this process

27
supervisor/sort.go Normal file
View file

@ -0,0 +1,27 @@
package supervisor
import (
"sort"
"github.com/docker/containerd/runtime"
)
func sortProcesses(p []runtime.Process) {
sort.Sort(&processSorter{p})
}
type processSorter struct {
processes []runtime.Process
}
func (s *processSorter) Len() int {
return len(s.processes)
}
func (s *processSorter) Swap(i, j int) {
s.processes[i], s.processes[j] = s.processes[j], s.processes[i]
}
func (s *processSorter) Less(i, j int) bool {
return s.processes[j].ID() == "init"
}

View file

@ -6,7 +6,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"sort"
"sync"
"time"
@ -20,7 +19,7 @@ const (
)
// New returns an initialized Process supervisor.
func New(stateDir string, oom bool) (*Supervisor, error) {
func New(stateDir string, oom bool, runtimeName string) (*Supervisor, error) {
startTasks := make(chan *startTask, 10)
if err := os.MkdirAll(stateDir, 0755); err != nil {
return nil, err
@ -41,6 +40,7 @@ func New(stateDir string, oom bool) (*Supervisor, error) {
subscribers: make(map[chan Event]struct{}),
tasks: make(chan Task, defaultBufferSize),
monitor: monitor,
runtime: runtimeName,
}
if err := setupEventLog(s); err != nil {
return nil, err
@ -116,7 +116,9 @@ func readEventLog(s *Supervisor) error {
type Supervisor struct {
// stateDir is the directory on the system to store container runtime state information.
stateDir string
stateDir string
// name of the OCI compatible runtime used to execute containers
runtime string
containers map[string]*containerInfo
startTasks chan *startTask
// we need a lock around the subscribers map only because additions and deletions from
@ -207,7 +209,12 @@ func (s *Supervisor) notifySubscribers(e Event) {
// therefore it is save to do operations in the handlers that modify state of the system or
// state of the Supervisor
func (s *Supervisor) Start() error {
logrus.WithField("stateDir", s.stateDir).Debug("containerd: supervisor running")
logrus.WithFields(logrus.Fields{
"stateDir": s.stateDir,
"runtime": s.runtime,
"memory": s.machine.Memory,
"cpus": s.machine.Cpus,
}).Debug("containerd: supervisor running")
go func() {
for i := range s.tasks {
s.handleTask(i)
@ -277,7 +284,7 @@ func (s *Supervisor) restore() error {
if len(exitedProcesses) > 0 {
// sort processes so that init is fired last because that is how the kernel sends the
// exit events
sort.Sort(&processSorter{exitedProcesses})
sortProcesses(exitedProcesses)
for _, p := range exitedProcesses {
e := &ExitTask{
Process: p,
@ -288,19 +295,3 @@ func (s *Supervisor) restore() error {
}
return nil
}
type processSorter struct {
processes []runtime.Process
}
func (s *processSorter) Len() int {
return len(s.processes)
}
func (s *processSorter) Swap(i, j int) {
s.processes[i], s.processes[j] = s.processes[j], s.processes[i]
}
func (s *processSorter) Less(i, j int) bool {
return s.processes[j].ID() == "init"
}

View file

@ -40,11 +40,15 @@ func (w *worker) Start() {
started := time.Now()
process, err := t.Container.Start(t.Checkpoint, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
"id": t.Container.ID(),
}).Error("containerd: start container")
t.Err <- err
evt := &DeleteTask{
ID: t.Container.ID(),
}
w.s.SendTask(evt)
t.Err <- err
continue
}
/*