k3s/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go

132 lines
2.8 KiB
Go
Raw Normal View History

2019-01-12 04:58:27 +00:00
// +build linux
package libcontainer
import (
"fmt"
"os"
2020-08-10 17:43:49 +00:00
"os/exec"
2019-01-12 04:58:27 +00:00
"github.com/opencontainers/runc/libcontainer/system"
)
2020-08-10 17:43:49 +00:00
func newRestoredProcess(cmd *exec.Cmd, fds []string) (*restoredProcess, error) {
2019-01-12 04:58:27 +00:00
var (
err error
)
2020-08-10 17:43:49 +00:00
pid := cmd.Process.Pid
2019-01-12 04:58:27 +00:00
stat, err := system.Stat(pid)
if err != nil {
return nil, err
}
return &restoredProcess{
2020-08-10 17:43:49 +00:00
cmd: cmd,
2019-01-12 04:58:27 +00:00
processStartTime: stat.StartTime,
fds: fds,
}, nil
}
type restoredProcess struct {
2020-08-10 17:43:49 +00:00
cmd *exec.Cmd
2019-01-12 04:58:27 +00:00
processStartTime uint64
fds []string
}
func (p *restoredProcess) start() error {
return newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
}
func (p *restoredProcess) pid() int {
2020-08-10 17:43:49 +00:00
return p.cmd.Process.Pid
2019-01-12 04:58:27 +00:00
}
func (p *restoredProcess) terminate() error {
2020-08-10 17:43:49 +00:00
err := p.cmd.Process.Kill()
2019-01-12 04:58:27 +00:00
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
2020-08-10 17:43:49 +00:00
err := p.cmd.Wait()
2019-01-12 04:58:27 +00:00
if err != nil {
2020-08-10 17:43:49 +00:00
if _, ok := err.(*exec.ExitError); !ok {
return nil, err
}
2019-01-12 04:58:27 +00:00
}
2020-08-10 17:43:49 +00:00
st := p.cmd.ProcessState
2019-01-12 04:58:27 +00:00
return st, nil
}
func (p *restoredProcess) startTime() (uint64, error) {
return p.processStartTime, nil
}
func (p *restoredProcess) signal(s os.Signal) error {
2020-08-10 17:43:49 +00:00
return p.cmd.Process.Signal(s)
2019-01-12 04:58:27 +00:00
}
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
2019-09-27 21:51:53 +00:00
}
2019-01-12 04:58:27 +00:00
// 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 newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
}
func (p *nonChildProcess) pid() int {
return p.processPid
}
func (p *nonChildProcess) terminate() error {
return newGenericError(fmt.Errorf("restored process cannot be terminated"), SystemError)
}
func (p *nonChildProcess) wait() (*os.ProcessState, error) {
return nil, newGenericError(fmt.Errorf("restored process cannot be waited on"), SystemError)
}
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
}
2019-09-27 21:51:53 +00:00
func (p *nonChildProcess) forwardChildLogs() chan error {
return nil
2019-09-27 21:51:53 +00:00
}