github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/restored_process.go (about) 1 package libcontainer 2 3 import ( 4 "errors" 5 "os" 6 "os/exec" 7 8 "github.com/opencontainers/runc/libcontainer/system" 9 ) 10 11 func newRestoredProcess(cmd *exec.Cmd, fds []string) (*restoredProcess, error) { 12 var err error 13 pid := cmd.Process.Pid 14 stat, err := system.Stat(pid) 15 if err != nil { 16 return nil, err 17 } 18 return &restoredProcess{ 19 cmd: cmd, 20 processStartTime: stat.StartTime, 21 fds: fds, 22 }, nil 23 } 24 25 type restoredProcess struct { 26 cmd *exec.Cmd 27 processStartTime uint64 28 fds []string 29 } 30 31 func (p *restoredProcess) start() error { 32 return errors.New("restored process cannot be started") 33 } 34 35 func (p *restoredProcess) pid() int { 36 return p.cmd.Process.Pid 37 } 38 39 func (p *restoredProcess) terminate() error { 40 err := p.cmd.Process.Kill() 41 if _, werr := p.wait(); err == nil { 42 err = werr 43 } 44 return err 45 } 46 47 func (p *restoredProcess) wait() (*os.ProcessState, error) { 48 // TODO: how do we wait on the actual process? 49 // maybe use --exec-cmd in criu 50 err := p.cmd.Wait() 51 if err != nil { 52 var exitErr *exec.ExitError 53 if !errors.As(err, &exitErr) { 54 return nil, err 55 } 56 } 57 st := p.cmd.ProcessState 58 return st, nil 59 } 60 61 func (p *restoredProcess) startTime() (uint64, error) { 62 return p.processStartTime, nil 63 } 64 65 func (p *restoredProcess) signal(s os.Signal) error { 66 return p.cmd.Process.Signal(s) 67 } 68 69 func (p *restoredProcess) externalDescriptors() []string { 70 return p.fds 71 } 72 73 func (p *restoredProcess) setExternalDescriptors(newFds []string) { 74 p.fds = newFds 75 } 76 77 func (p *restoredProcess) forwardChildLogs() chan error { 78 return nil 79 } 80 81 // nonChildProcess represents a process where the calling process is not 82 // the parent process. This process is created when Load loads a container 83 // from a persisted state. 84 type nonChildProcess struct { 85 processPid int 86 processStartTime uint64 87 fds []string 88 } 89 90 func (p *nonChildProcess) start() error { 91 return errors.New("restored process cannot be started") 92 } 93 94 func (p *nonChildProcess) pid() int { 95 return p.processPid 96 } 97 98 func (p *nonChildProcess) terminate() error { 99 return errors.New("restored process cannot be terminated") 100 } 101 102 func (p *nonChildProcess) wait() (*os.ProcessState, error) { 103 return nil, errors.New("restored process cannot be waited on") 104 } 105 106 func (p *nonChildProcess) startTime() (uint64, error) { 107 return p.processStartTime, nil 108 } 109 110 func (p *nonChildProcess) signal(s os.Signal) error { 111 proc, err := os.FindProcess(p.processPid) 112 if err != nil { 113 return err 114 } 115 return proc.Signal(s) 116 } 117 118 func (p *nonChildProcess) externalDescriptors() []string { 119 return p.fds 120 } 121 122 func (p *nonChildProcess) setExternalDescriptors(newFds []string) { 123 p.fds = newFds 124 } 125 126 func (p *nonChildProcess) forwardChildLogs() chan error { 127 return nil 128 }