From 7d6149063a0bb6e563885a8f199756e7af5e69cf Mon Sep 17 00:00:00 2001 From: Brielle Broder Date: Thu, 21 Jun 2018 09:57:33 -0700 Subject: Restore implementation added to runsc. Restore creates a new container and uses the given image-path to load a saved image of a previous container. Restore command is plumbed through container and sandbox. This command does not work yet - more to come. PiperOrigin-RevId: 201541229 Change-Id: I864a14c799ce3717d99bcdaaebc764281863d06f --- runsc/sandbox/sandbox.go | 26 ++++++++++++++++++++++---- runsc/sandbox/sandbox_test.go | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'runsc/sandbox') diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 652910efa..870a0ccd3 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -54,7 +54,9 @@ type Sandbox struct { } // Create creates the sandbox process. -func Create(id string, spec *specs.Spec, conf *boot.Config, bundleDir, consoleSocket string) (*Sandbox, error) { +// +// If restoreFile is not empty, the sandbox will be restored from file. +func Create(id string, spec *specs.Spec, conf *boot.Config, bundleDir, consoleSocket string, restoreFile string) (*Sandbox, error) { s := &Sandbox{ID: id} binPath, err := specutils.BinPath() @@ -69,7 +71,7 @@ func Create(id string, spec *specs.Spec, conf *boot.Config, bundleDir, consoleSo } // Create the sandbox process. - if err := s.createSandboxProcess(spec, conf, bundleDir, consoleSocket, binPath, ioFiles); err != nil { + if err := s.createSandboxProcess(spec, conf, bundleDir, consoleSocket, binPath, ioFiles, restoreFile); err != nil { return nil, err } @@ -251,7 +253,7 @@ func (s *Sandbox) createGoferProcess(spec *specs.Spec, conf *boot.Config, bundle // createSandboxProcess starts the sandbox as a subprocess by running the "boot" // command, passing in the bundle dir. -func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bundleDir, consoleSocket, binPath string, ioFiles []*os.File) error { +func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bundleDir, consoleSocket, binPath string, ioFiles []*os.File, restoreFile string) error { // nextFD is used to get unused FDs that we can pass to the sandbox. It // starts at 3 because 0, 1, and 2 are taken by stdin/out/err. nextFD := 3 @@ -273,12 +275,27 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund "--bundle", bundleDir, "--controller-fd="+strconv.Itoa(nextFD), fmt.Sprintf("--console=%t", consoleEnabled)) - nextFD++ controllerFile := os.NewFile(uintptr(fd), "control_server_socket") defer controllerFile.Close() cmd.ExtraFiles = append(cmd.ExtraFiles, controllerFile) + // If a restore filename was given, open the file and append its FD to Args + // and the file to ExtraFiles. + if restoreFile != "" { + // Create the image file and open for reading. + rF, err := os.Open(restoreFile) + if err != nil { + return fmt.Errorf("os.Open(%q) failed: %v", restoreFile, err) + } + defer rF.Close() + + nextFD++ + cmd.Args = append(cmd.Args, "--restore-fd="+strconv.Itoa(nextFD)) + cmd.ExtraFiles = append(cmd.ExtraFiles, rF) + } + nextFD++ + // If there is a gofer, sends all socket ends to the sandbox. for _, f := range ioFiles { defer f.Close() @@ -379,6 +396,7 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund } s.Pid = cmd.Process.Pid log.Infof("Sandbox started, pid: %d", s.Pid) + return nil } diff --git a/runsc/sandbox/sandbox_test.go b/runsc/sandbox/sandbox_test.go index fee2de283..9db90ef07 100644 --- a/runsc/sandbox/sandbox_test.go +++ b/runsc/sandbox/sandbox_test.go @@ -39,7 +39,7 @@ func TestGoferExits(t *testing.T) { defer os.RemoveAll(bundleDir) // Create, start and wait for the container. - s, err := Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "") + s, err := Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "", "") if err != nil { t.Fatalf("error creating container: %v", err) } -- cgit v1.2.3