github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/shim/proc/exec_state.go (about) 1 // Copyright 2018 The containerd Authors. 2 // Copyright 2018 The gVisor Authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // https://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package proc 17 18 import ( 19 "context" 20 "fmt" 21 22 "github.com/containerd/console" 23 ) 24 25 type execState interface { 26 Resize(console.WinSize) error 27 Start(context.Context) error 28 Delete(context.Context) error 29 Kill(context.Context, uint32, bool) error 30 SetExited(int) 31 } 32 33 type execCreatedState struct { 34 p *execProcess 35 } 36 37 func (s *execCreatedState) name() string { 38 return "created" 39 } 40 41 func (s *execCreatedState) transition(transition stateTransition) { 42 switch transition { 43 case running: 44 s.p.execState = &execRunningState{p: s.p} 45 case stopped: 46 s.p.execState = &execStoppedState{p: s.p} 47 case deleted: 48 s.p.execState = &deletedState{} 49 default: 50 panic(fmt.Sprintf("invalid state transition %q to %q", s.name(), transition)) 51 } 52 } 53 54 func (s *execCreatedState) Resize(ws console.WinSize) error { 55 return s.p.resize(ws) 56 } 57 58 func (s *execCreatedState) Start(ctx context.Context) error { 59 if err := s.p.start(ctx); err != nil { 60 return err 61 } 62 s.transition(running) 63 return nil 64 } 65 66 func (s *execCreatedState) Delete(context.Context) error { 67 s.p.delete() 68 s.transition(deleted) 69 return nil 70 } 71 72 func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error { 73 return s.p.kill(ctx, sig, all) 74 } 75 76 func (s *execCreatedState) SetExited(status int) { 77 s.p.setExited(status) 78 s.transition(stopped) 79 } 80 81 type execRunningState struct { 82 p *execProcess 83 } 84 85 func (s *execRunningState) name() string { 86 return "running" 87 } 88 89 func (s *execRunningState) transition(transition stateTransition) { 90 switch transition { 91 case stopped: 92 s.p.execState = &execStoppedState{p: s.p} 93 default: 94 panic(fmt.Sprintf("invalid state transition %q to %q", s.name(), transition)) 95 } 96 } 97 98 func (s *execRunningState) Resize(ws console.WinSize) error { 99 return s.p.resize(ws) 100 } 101 102 func (s *execRunningState) Start(context.Context) error { 103 return fmt.Errorf("cannot start a running process") 104 } 105 106 func (s *execRunningState) Delete(context.Context) error { 107 return fmt.Errorf("cannot delete a running process") 108 } 109 110 func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error { 111 return s.p.kill(ctx, sig, all) 112 } 113 114 func (s *execRunningState) SetExited(status int) { 115 s.p.setExited(status) 116 s.transition(stopped) 117 } 118 119 type execStoppedState struct { 120 p *execProcess 121 } 122 123 func (s *execStoppedState) name() string { 124 return "stopped" 125 } 126 127 func (s *execStoppedState) transition(transition stateTransition) { 128 switch transition { 129 case deleted: 130 s.p.execState = &deletedState{} 131 default: 132 panic(fmt.Sprintf("invalid state transition %q to %q", s.name(), transition)) 133 } 134 } 135 136 func (s *execStoppedState) Resize(console.WinSize) error { 137 return fmt.Errorf("cannot resize a stopped container") 138 } 139 140 func (s *execStoppedState) Start(context.Context) error { 141 return fmt.Errorf("cannot start a stopped process") 142 } 143 144 func (s *execStoppedState) Delete(context.Context) error { 145 s.p.delete() 146 s.transition(deleted) 147 return nil 148 } 149 150 func (s *execStoppedState) Kill(_ context.Context, sig uint32, _ bool) error { 151 return handleStoppedKill(sig) 152 } 153 154 func (s *execStoppedState) SetExited(int) { 155 // no op 156 }