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:
parent
5fb0019c45
commit
522f7b36ff
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue