summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/sandbox')
-rw-r--r--runsc/sandbox/sandbox.go71
-rw-r--r--runsc/sandbox/sandbox_test.go2
2 files changed, 52 insertions, 21 deletions
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index 9200fbee9..1f2cd6018 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -56,7 +56,7 @@ type Sandbox struct {
// Create creates the sandbox process.
//
// 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) {
+func Create(id string, spec *specs.Spec, conf *boot.Config, bundleDir, consoleSocket string) (*Sandbox, error) {
s := &Sandbox{ID: id}
binPath, err := specutils.BinPath()
@@ -71,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, restoreFile); err != nil {
+ if err := s.createSandboxProcess(spec, conf, bundleDir, consoleSocket, binPath, ioFiles); err != nil {
return nil, err
}
@@ -127,6 +127,42 @@ func (s *Sandbox) Start(spec *specs.Spec, conf *boot.Config, cid string) error {
return nil
}
+// Restore sends the restore call for a container in the sandbox.
+func (s *Sandbox) Restore(cid string, spec *specs.Spec, conf *boot.Config, f string) error {
+ log.Debugf("Restore sandbox %q", s.ID)
+
+ rf, err := os.Open(f)
+ if err != nil {
+ return fmt.Errorf("os.Open(%q) failed: %v", f, err)
+ }
+ defer rf.Close()
+
+ opt := boot.RestoreOpts{
+ FilePayload: urpc.FilePayload{
+ Files: []*os.File{rf},
+ },
+ SandboxID: s.ID,
+ }
+
+ conn, err := s.connect()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+
+ // Configure the network.
+ if err := setupNetwork(conn, s.Pid, spec, conf); err != nil {
+ return fmt.Errorf("error setting up network: %v", err)
+ }
+
+ // Restore the container and start the root container.
+ if err := conn.Call(boot.ContainerRestore, &opt, nil); err != nil {
+ return fmt.Errorf("error restoring container %q: %v", cid, err)
+ }
+
+ return nil
+}
+
// Processes retrieves the list of processes and associated metadata for a
// given container in this sandbox.
func (s *Sandbox) Processes(cid string) ([]*control.Process, error) {
@@ -254,7 +290,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, restoreFile string) error {
+func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bundleDir, consoleSocket, binPath string, ioFiles []*os.File) 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
@@ -276,27 +312,12 @@ 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()
@@ -402,7 +423,8 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
}
// waitForCreated waits for the sandbox subprocess control server to be
-// running, at which point the sandbox is in Created state.
+// running and for the loader to have been created, at which point the sandbox
+// is in Created state.
func (s *Sandbox) waitForCreated(timeout time.Duration) error {
log.Debugf("Waiting for sandbox %q creation", s.ID)
@@ -418,6 +440,15 @@ func (s *Sandbox) waitForCreated(timeout time.Duration) error {
if err := specutils.WaitForReady(s.Pid, timeout, ready); err != nil {
return fmt.Errorf("unexpected error waiting for sandbox %q, err: %v", s.ID, err)
}
+ conn, err := s.connect()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+
+ if err := conn.Call(boot.ContainerWaitForLoader, nil, nil); err != nil {
+ return fmt.Errorf("err waiting on loader on sandbox %q, err: %v", s.ID, err)
+ }
return nil
}
diff --git a/runsc/sandbox/sandbox_test.go b/runsc/sandbox/sandbox_test.go
index 9db90ef07..fee2de283 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)
}