...

Source file src/github.com/opencontainers/runc/libcontainer/restored_process.go

Documentation: github.com/opencontainers/runc/libcontainer

     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 a factory loads a container from
    83  // 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  }
   129  

View as plain text