Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Signed-off-by: Lantao Liu <lantaol@google.com>
  • Loading branch information
Random-Liu committed Jan 28, 2019
1 parent ba9cd39 commit dfeac76
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 98 deletions.
37 changes: 36 additions & 1 deletion pkg/v1/proc/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import (
type execProcess struct {
wg sync.WaitGroup

proc.State
execState execState

mu sync.Mutex
id string
Expand Down Expand Up @@ -88,13 +88,27 @@ func (e *execProcess) ExitedAt() time.Time {
return e.exited
}

func (e *execProcess) SetExited(status int) {
e.mu.Lock()
defer e.mu.Unlock()

e.execState.SetExited(status)
}

func (e *execProcess) setExited(status int) {
e.status = status
e.exited = time.Now()
e.parent.Platform.ShutdownConsole(context.Background(), e.console)
close(e.waitBlock)
}

func (e *execProcess) Delete(ctx context.Context) error {
e.mu.Lock()
defer e.mu.Unlock()

return e.execState.Delete(ctx)
}

func (e *execProcess) delete(ctx context.Context) error {
e.wg.Wait()
if e.io != nil {
Expand All @@ -112,13 +126,27 @@ func (e *execProcess) delete(ctx context.Context) error {
return nil
}

func (e *execProcess) Resize(ws console.WinSize) error {
e.mu.Lock()
defer e.mu.Unlock()

return e.execState.Resize(ws)
}

func (e *execProcess) resize(ws console.WinSize) error {
if e.console == nil {
return nil
}
return e.console.Resize(ws)
}

func (e *execProcess) Kill(ctx context.Context, sig uint32, _ bool) error {
e.mu.Lock()
defer e.mu.Unlock()

return e.execState.Kill(ctx, sig, false)
}

func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
internalPid := e.internalPid
if internalPid != 0 {
Expand All @@ -141,6 +169,13 @@ func (e *execProcess) Stdio() proc.Stdio {
return e.stdio
}

func (e *execProcess) Start(ctx context.Context) error {
e.mu.Lock()
defer e.mu.Unlock()

return e.execState.Start(ctx)
}

func (e *execProcess) start(ctx context.Context) (err error) {
var (
socket *runc.Socket
Expand Down
57 changes: 13 additions & 44 deletions pkg/v1/proc/exec_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,37 @@ import (
"github.com/pkg/errors"
)

type execState interface {
Resize(console.WinSize) error
Start(context.Context) error
Delete(context.Context) error
Kill(context.Context, uint32, bool) error
SetExited(int)
}

type execCreatedState struct {
p *execProcess
}

func (s *execCreatedState) transition(name string) error {
switch name {
case "running":
s.p.State = &execRunningState{p: s.p}
s.p.execState = &execRunningState{p: s.p}
case "stopped":
s.p.State = &execStoppedState{p: s.p}
s.p.execState = &execStoppedState{p: s.p}
case "deleted":
s.p.State = &deletedState{}
s.p.execState = &deletedState{}
default:
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}

func (s *execCreatedState) Resize(ws console.WinSize) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return s.p.resize(ws)
}

func (s *execCreatedState) Start(ctx context.Context) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()
if err := s.p.start(ctx); err != nil {
return err
}
Expand All @@ -62,22 +65,14 @@ func (s *execCreatedState) Delete(ctx context.Context) error {
if err := s.p.delete(ctx); err != nil {
return err
}
s.p.mu.Lock()
defer s.p.mu.Unlock()
return s.transition("deleted")
}

func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return s.p.kill(ctx, sig, all)
}

func (s *execCreatedState) SetExited(status int) {
s.p.mu.Lock()
defer s.p.mu.Unlock()

s.p.setExited(status)

if err := s.transition("stopped"); err != nil {
Expand All @@ -92,45 +87,30 @@ type execRunningState struct {
func (s *execRunningState) transition(name string) error {
switch name {
case "stopped":
s.p.State = &execStoppedState{p: s.p}
s.p.execState = &execStoppedState{p: s.p}
default:
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}

func (s *execRunningState) Resize(ws console.WinSize) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return s.p.resize(ws)
}

func (s *execRunningState) Start(ctx context.Context) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return errors.Errorf("cannot start a running process")
}

func (s *execRunningState) Delete(ctx context.Context) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return errors.Errorf("cannot delete a running process")
}

func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return s.p.kill(ctx, sig, all)
}

func (s *execRunningState) SetExited(status int) {
s.p.mu.Lock()
defer s.p.mu.Unlock()

s.p.setExited(status)

if err := s.transition("stopped"); err != nil {
Expand All @@ -145,40 +125,29 @@ type execStoppedState struct {
func (s *execStoppedState) transition(name string) error {
switch name {
case "deleted":
s.p.State = &deletedState{}
s.p.execState = &deletedState{}
default:
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}

func (s *execStoppedState) Resize(ws console.WinSize) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return errors.Errorf("cannot resize a stopped container")
}

func (s *execStoppedState) Start(ctx context.Context) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return errors.Errorf("cannot start a stopped process")
}

func (s *execStoppedState) Delete(ctx context.Context) error {
if err := s.p.delete(ctx); err != nil {
return err
}
s.p.mu.Lock()
defer s.p.mu.Unlock()
return s.transition("deleted")
}

func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error {
s.p.mu.Lock()
defer s.p.mu.Unlock()

return s.p.kill(ctx, sig, all)
}

Expand Down
67 changes: 59 additions & 8 deletions pkg/v1/proc/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ const InitPidFile = "init.pid"

// Init represents an initial process for a container
type Init struct {
wg sync.WaitGroup
initState
wg sync.WaitGroup
initState initState

// mu is used to ensure that `Start()` and `Exited()` calls return in
// the right order when invoked in separate go routines.
Expand Down Expand Up @@ -217,6 +217,14 @@ func (p *Init) Status(ctx context.Context) (string, error) {
return p.convertStatus(c.Status), nil
}

// Start the init process
func (p *Init) Start(ctx context.Context) error {
p.mu.Lock()
defer p.mu.Unlock()

return p.initState.Start(ctx)
}

func (p *Init) start(context context.Context) error {
var cio runc.IO
if !p.Sandbox {
Expand Down Expand Up @@ -244,17 +252,33 @@ func (p *Init) start(context context.Context) error {
return nil
}

// SetExited of the init process with the next status
func (p *Init) SetExited(status int) {
p.mu.Lock()
defer p.mu.Unlock()

p.initState.SetExited(status)
}

func (p *Init) setExited(status int) {
p.exited = time.Now()
p.status = status
p.Platform.ShutdownConsole(context.Background(), p.console)
close(p.waitBlock)
}

func (p *Init) delete(context context.Context) error {
p.killAll(context)
// Delete the init process
func (p *Init) Delete(ctx context.Context) error {
p.mu.Lock()
defer p.mu.Unlock()

return p.initState.Delete(ctx)
}

func (p *Init) delete(ctx context.Context) error {
p.killAll(ctx)
p.wg.Wait()
err := p.runtime.Delete(context, p.id, nil)
err := p.runtime.Delete(ctx, p.id, nil)
// ignore errors if a runtime has already deleted the process
// but we still hold metadata and pipes
//
Expand All @@ -274,21 +298,40 @@ func (p *Init) delete(context context.Context) error {
p.io.Close()
}
if err2 := mount.UnmountAll(p.Rootfs, 0); err2 != nil {
log.G(context).WithError(err2).Warn("failed to cleanup rootfs mount")
log.G(ctx).WithError(err2).Warn("failed to cleanup rootfs mount")
if err == nil {
err = errors.Wrap(err2, "failed rootfs umount")
}
}
return err
}

// Resize the init processes console
func (p *Init) Resize(ws console.WinSize) error {
p.mu.Lock()
defer p.mu.Unlock()

if p.console == nil {
return nil
}
return p.console.Resize(ws)
}

func (p *Init) resize(ws console.WinSize) error {
if p.console == nil {
return nil
}
return p.console.Resize(ws)
}

// Kill the init process
func (p *Init) Kill(ctx context.Context, signal uint32, all bool) error {
p.mu.Lock()
defer p.mu.Unlock()

return p.initState.Kill(ctx, signal, all)
}

func (p *Init) kill(context context.Context, signal uint32, all bool) error {
var (
killErr error
Expand Down Expand Up @@ -349,8 +392,16 @@ func (p *Init) Runtime() *runsc.Runsc {
return p.runtime
}

// Exec returns a new child process
func (p *Init) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
p.mu.Lock()
defer p.mu.Unlock()

return p.initState.Exec(ctx, path, r)
}

// exec returns a new exec'd process
func (p *Init) exec(context context.Context, path string, r *ExecConfig) (proc.Process, error) {
func (p *Init) exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
// process exec request
var spec specs.Process
if err := json.Unmarshal(r.Spec.Value, &spec); err != nil {
Expand All @@ -371,7 +422,7 @@ func (p *Init) exec(context context.Context, path string, r *ExecConfig) (proc.P
},
waitBlock: make(chan struct{}),
}
e.State = &execCreatedState{p: e}
e.execState = &execCreatedState{p: e}
return e, nil
}

Expand Down
Loading

0 comments on commit dfeac76

Please sign in to comment.