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