cr: Add an ability to specify path for images

the emptye /ROOT/CTID/checkpoint file is created to
support the Checkpointed state.

Signed-off-by: Andrey Vagin <avagin@openvz.org>
This commit is contained in:
Andrey Vagin 2015-04-10 15:48:28 +03:00 committed by Michael Crosby
parent 5fb0019c45
commit 522f7b36ff
4 changed files with 34 additions and 22 deletions

View File

@ -115,13 +115,13 @@ type Container interface {
//
// errors:
// Systemerror - System error.
Checkpoint() error
Checkpoint(string) error
// Restore restores the checkpointed container to a running state using the criu(8) utiity.
//
// errors:
// Systemerror - System error.
Restore(*Process) error
Restore(*Process, string) error
// Destroys the container after killing all running processes.
//

View File

@ -289,7 +289,7 @@ func (c *linuxContainer) checkCriuVersion() error {
return nil
}
func (c *linuxContainer) Checkpoint() error {
func (c *linuxContainer) Checkpoint(imagePath string) error {
c.m.Lock()
defer c.m.Unlock()
@ -297,12 +297,6 @@ func (c *linuxContainer) Checkpoint() error {
return err
}
imagePath := filepath.Join(c.root, "checkpoint")
// Since a container can be C/R'ed multiple times,
// the checkpoint directory may already exist.
if err := os.Mkdir(imagePath, 0655); err != nil && !os.IsExist(err) {
return err
}
workPath := filepath.Join(c.root, "criu.work")
if err := os.Mkdir(workPath, 0655); err != nil && !os.IsExist(err) {
return err
@ -322,6 +316,11 @@ func (c *linuxContainer) Checkpoint() error {
"--ext-mount-map", fmt.Sprintf("%s:%s", m.Destination, m.Destination))
}
}
f, err := os.Create(filepath.Join(c.root, "checkpoint"))
if err != nil {
return err
}
f.Close()
addArgsFromEnv("CRIU_C", &args) // XXX debug
if err := exec.Command(c.criuPath, args...).Run(); err != nil {
return err
@ -330,7 +329,7 @@ func (c *linuxContainer) Checkpoint() error {
return nil
}
func (c *linuxContainer) Restore(process *Process) error {
func (c *linuxContainer) Restore(process *Process, imagePath string) error {
c.m.Lock()
defer c.m.Unlock()
@ -338,13 +337,6 @@ func (c *linuxContainer) Restore(process *Process) error {
return err
}
pidfile := filepath.Join(c.root, "restoredpid")
// Make sure pidfile doesn't already exist from a
// previous restore. Otherwise, CRIU will fail.
if err := os.Remove(pidfile); err != nil && !os.IsNotExist(err) {
return err
}
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET|syscall.SOCK_CLOEXEC, 0)
if err != nil {
return err
@ -367,7 +359,6 @@ func (c *linuxContainer) Restore(process *Process) error {
}
defer workDir.Close()
imagePath := filepath.Join(c.root, "checkpoint")
imageDir, err := os.Open(imagePath)
if err != nil {
return err
@ -563,7 +554,7 @@ func (c *linuxContainer) updateState(process parentProcess) error {
return err
}
defer f.Close()
os.RemoveAll(filepath.Join(c.root, "checkpoint"))
os.Remove(filepath.Join(c.root, "checkpoint"))
return json.NewEncoder(f).Encode(state)
}

View File

@ -1,19 +1,34 @@
package main
import "github.com/codegangsta/cli"
import (
"fmt"
"os"
"github.com/codegangsta/cli"
)
var checkpointCommand = cli.Command{
Name: "checkpoint",
Usage: "checkpoint a running container",
Flags: []cli.Flag{
cli.StringFlag{Name: "id", Value: "nsinit", Usage: "specify the ID for a container"},
cli.StringFlag{Name: "image-path", Value: "", Usage: "path where to save images"},
},
Action: func(context *cli.Context) {
imagePath := context.String("image-path")
if imagePath == "" {
fatal(fmt.Errorf("The --image-path option isn't specified"))
}
container, err := getContainer(context)
if err != nil {
fatal(err)
}
if err := container.Checkpoint(); err != nil {
// Since a container can be C/R'ed multiple times,
// the checkpoint directory may already exist.
if err := os.Mkdir(imagePath, 0655); err != nil && !os.IsExist(err) {
fatal(err)
}
if err := container.Checkpoint(imagePath); err != nil {
fatal(err)
}
},

View File

@ -1,6 +1,7 @@
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
@ -15,8 +16,13 @@ var restoreCommand = cli.Command{
Usage: "restore a container from a previous checkpoint",
Flags: []cli.Flag{
cli.StringFlag{Name: "id", Value: "nsinit", Usage: "specify the ID for a container"},
cli.StringFlag{Name: "image-path", Value: "", Usage: "path where to save images"},
},
Action: func(context *cli.Context) {
imagePath := context.String("image-path")
if imagePath == "" {
fatal(fmt.Errorf("The --image-path option isn't specified"))
}
container, err := getContainer(context)
if err != nil {
fatal(err)
@ -38,7 +44,7 @@ var restoreCommand = cli.Command{
if err := tty.attach(process); err != nil {
fatal(err)
}
err = container.Restore(process)
err = container.Restore(process, imagePath)
if err != nil {
fatal(err)
}