diff --git a/container_linux.go b/container_linux.go index 1938c91ae..d55e16adf 100644 --- a/container_linux.go +++ b/container_linux.go @@ -110,7 +110,6 @@ func (c *linuxContainer) Start(process *Process) error { } process.ops = parent if doInit { - c.updateState(parent) } return nil @@ -257,9 +256,13 @@ func (c *linuxContainer) NotifyOOM() (<-chan struct{}, error) { } func (c *linuxContainer) Checkpoint() error { + dir := filepath.Join(c.root, "checkpoint") + if err := os.Mkdir(dir, 0655); err != nil { + return err + } args := []string{ "dump", "-v4", - "-D", filepath.Join(c.root, "checkpoint"), + "-D", dir, "-o", "dump.log", "--root", c.config.Rootfs, "--manage-cgroups", "--evasive-devices", diff --git a/nsinit/checkpoint.go b/nsinit/checkpoint.go new file mode 100644 index 000000000..f1e3130e4 --- /dev/null +++ b/nsinit/checkpoint.go @@ -0,0 +1,20 @@ +package main + +import "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"}, + }, + Action: func(context *cli.Context) { + container, err := getContainer(context) + if err != nil { + fatal(err) + } + if err := container.Checkpoint(); err != nil { + fatal(err) + } + }, +} diff --git a/nsinit/main.go b/nsinit/main.go index 0a59c9f1e..a035a5b97 100644 --- a/nsinit/main.go +++ b/nsinit/main.go @@ -13,19 +13,22 @@ func main() { app.Version = "2" app.Author = "libcontainer maintainers" app.Flags = []cli.Flag{ - cli.StringFlag{Name: "root", Value: "/var/run/nsinit", Usage: "root directory for containers"}, - cli.StringFlag{Name: "log-file", Value: "", Usage: "set the log file to output logs to"}, cli.BoolFlag{Name: "debug", Usage: "enable debug output in the logs"}, + cli.StringFlag{Name: "root", Value: "/var/run/nsinit", Usage: "root directory for containers"}, + cli.StringFlag{Name: "log-file", Usage: "set the log file to output logs to"}, + cli.StringFlag{Name: "criu", Usage: "path to the criu binary for checkpoint and restore"}, } app.Commands = []cli.Command{ + checkpointCommand, configCommand, execCommand, initCommand, oomCommand, pauseCommand, + stateCommand, statsCommand, unpauseCommand, - stateCommand, + restoreCommand, } app.Before = func(context *cli.Context) error { if context.GlobalBool("debug") { diff --git a/nsinit/restore.go b/nsinit/restore.go new file mode 100644 index 000000000..f5a329eaa --- /dev/null +++ b/nsinit/restore.go @@ -0,0 +1,20 @@ +package main + +import "github.com/codegangsta/cli" + +var restoreCommand = cli.Command{ + Name: "restore", + Usage: "restore a container from a previous checkpoint", + Flags: []cli.Flag{ + cli.StringFlag{Name: "id", Value: "nsinit", Usage: "specify the ID for a container"}, + }, + Action: func(context *cli.Context) { + container, err := getContainer(context) + if err != nil { + fatal(err) + } + if err := container.Restore(); err != nil { + fatal(err) + } + }, +} diff --git a/nsinit/utils.go b/nsinit/utils.go index fe9d0efe3..162b189ad 100644 --- a/nsinit/utils.go +++ b/nsinit/utils.go @@ -3,9 +3,10 @@ package main import ( "encoding/json" "fmt" - "github.com/Sirupsen/logrus" "os" + "github.com/Sirupsen/logrus" + "github.com/codegangsta/cli" "github.com/docker/libcontainer" "github.com/docker/libcontainer/cgroups/systemd" @@ -39,7 +40,10 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) { logrus.Warn("systemd cgroup flag passed, but systemd support for managing cgroups is not available.") } } - return libcontainer.New(context.GlobalString("root"), cgm) + return libcontainer.New(context.GlobalString("root"), cgm, func(l *libcontainer.LinuxFactory) error { + l.CriuPath = context.GlobalString("criu") + return nil + }) } func getContainer(context *cli.Context) (libcontainer.Container, error) {