Created
April 28, 2015 18:49
-
-
Save boucher/08faf44aa51934883de6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/configs/config.go b/configs/config.go | |
| index 33c9fc0..b07f252 100644 | |
| --- a/configs/config.go | |
| +++ b/configs/config.go | |
| @@ -96,9 +96,6 @@ type Config struct { | |
| // ReadonlyPaths specifies paths within the container's rootfs to remount as read-only | |
| // so that these files prevent any writes. | |
| ReadonlyPaths []string `json:"readonly_paths"` | |
| - | |
| - // Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore | |
| - StdFds [3]string `json:"ext_pipes,omitempty"` | |
| } | |
| // Gets the root uid for the process on host which could be non-zero | |
| diff --git a/container.go b/container.go | |
| index b954272..5698361 100644 | |
| --- a/container.go | |
| +++ b/container.go | |
| @@ -49,6 +49,9 @@ type State struct { | |
| // Config is the container's configuration. | |
| Config configs.Config `json:"config"` | |
| + | |
| + // Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore | |
| + StdFds [3]string `json:"ext_pipes,omitempty"` | |
| } | |
| // A libcontainer container object. | |
| diff --git a/container_linux.go b/container_linux.go | |
| index 6011f39..1b6ad54 100644 | |
| --- a/container_linux.go | |
| +++ b/container_linux.go | |
| @@ -369,7 +369,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error { | |
| // Write the FD info to a file in the image directory | |
| - fdsJSON, err := json.Marshal(c.config.StdFds) | |
| + fdsJSON, err := json.Marshal(c.initProcess.stdFds()) | |
| if err != nil { | |
| return err | |
| } | |
| @@ -557,7 +558,7 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts * | |
| }() | |
| if process != nil { | |
| - err = saveStdPipes(cmd.Process.Pid, c.config) | |
| + err = c.initProcess.saveStdPipes() | |
| if err != nil { | |
| return err | |
| } | |
| @@ -768,6 +769,7 @@ func (c *linuxContainer) currentState() (*State, error) { | |
| InitProcessStartTime: startTime, | |
| CgroupPaths: c.cgroupManager.GetPaths(), | |
| NamespacePaths: make(map[configs.NamespaceType]string), | |
| + StdFds: c.initProcess.stdFds(), | |
| } | |
| for _, ns := range c.config.Namespaces { | |
| state.NamespacePaths[ns.Type] = ns.GetPath(c.initProcess.pid()) | |
| diff --git a/process_linux.go b/process_linux.go | |
| index e3934a3..0f15bd8 100644 | |
| --- a/process_linux.go | |
| +++ b/process_linux.go | |
| @@ -13,7 +13,6 @@ import ( | |
| "syscall" | |
| "github.com/docker/libcontainer/cgroups" | |
| - "github.com/docker/libcontainer/configs" | |
| "github.com/docker/libcontainer/system" | |
| ) | |
| @@ -34,6 +33,10 @@ type parentProcess interface { | |
| startTime() (string, error) | |
| signal(os.Signal) error | |
| + | |
| + stdFds() [3]string | |
| + | |
| + saveStdPipes() error | |
| } | |
| type setnsProcess struct { | |
| @@ -142,18 +145,32 @@ func (p *setnsProcess) pid() int { | |
| return p.cmd.Process.Pid | |
| } | |
| +func (p *setnsProcess) stdFds() [3]string { | |
| + return [3]string{"", "", ""} | |
| +} | |
| + | |
| +func (p *setnsProcess) saveStdPipes() error { | |
| + return nil | |
| +} | |
| + | |
| type initProcess struct { | |
| cmd *exec.Cmd | |
| parentPipe *os.File | |
| childPipe *os.File | |
| config *initConfig | |
| manager cgroups.Manager | |
| + container *linuxContainer | |
| + fds [3]string | |
| } | |
| func (p *initProcess) pid() int { | |
| return p.cmd.Process.Pid | |
| } | |
| +func (p *initProcess) stdFds() [3]string { | |
| + return p.fds | |
| +} | |
| + | |
| func (p *initProcess) start() error { | |
| defer p.parentPipe.Close() | |
| err := p.cmd.Start() | |
| @@ -164,7 +181,7 @@ func (p *initProcess) start() error { | |
| // Save the standard descriptor names before the container process | |
| // can potentially move them (e.g., via dup2()). If we don't do this now, | |
| // we won't know at checkpoint time which file descriptor to look up. | |
| - if err = saveStdPipes(p.pid(), p.config.Config); err != nil { | |
| + if err = p.saveStdPipes(); err != nil { | |
| return newSystemError(err) | |
| } | |
| // Do this before syncing with child so that no children | |
| @@ -260,15 +277,15 @@ func (p *initProcess) signal(sig os.Signal) error { | |
| // Save process's std{in,out,err} file names as these will be | |
| // removed if/when the container is checkpointed. We will need | |
| // this info to restore the container. | |
| -func saveStdPipes(pid int, config *configs.Config) error { | |
| - dirPath := filepath.Join("/proc", strconv.Itoa(pid), "/fd") | |
| +func (p *initProcess) saveStdPipes() error { | |
| + dirPath := filepath.Join("/proc", strconv.Itoa(p.pid()), "/fd") | |
| for i := 0; i < 3; i++ { | |
| f := filepath.Join(dirPath, strconv.Itoa(i)) | |
| target, err := os.Readlink(f) | |
| if err != nil { | |
| return err | |
| } | |
| - config.StdFds[i] = target | |
| + p.fds[i] = target | |
| } | |
| return nil | |
| } | |
| diff --git a/restored_process.go b/restored_process.go | |
| index ae60e6e..629eab9 100644 | |
| --- a/restored_process.go | |
| +++ b/restored_process.go | |
| @@ -66,6 +66,14 @@ func (p *restoredProcess) signal(s os.Signal) error { | |
| return p.proc.Signal(s) | |
| } | |
| +func (p *restoredProcess) stdFds() [3]string { | |
| + return [3]string{"", "", ""} | |
| +} | |
| + | |
| +func (p *restoredProcess) saveStdPipes() 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. | |
| @@ -97,3 +105,11 @@ func (p *nonChildProcess) startTime() (string, error) { | |
| func (p *nonChildProcess) signal(s os.Signal) error { | |
| return newGenericError(fmt.Errorf("restored process cannot be signaled"), SystemError) | |
| } | |
| + | |
| +func (p *nonChildProcess) stdFds() [3]string { | |
| + return [3]string{"", "", ""} | |
| +} | |
| + | |
| +func (p *nonChildProcess) saveStdPipes() error { | |
| + return newGenericError(fmt.Errorf("restored process cannot save stdfds"), SystemError) | |
| +} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment