summaryrefslogtreecommitdiffhomepage
path: root/runsc/boot
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@gmail.com>2019-05-03 21:40:48 -0700
committerShentubot <shentubot@google.com>2019-05-03 21:41:45 -0700
commitbf0ac565d2873069799082ad7bc3e3c43acbc593 (patch)
tree398abb381e328568809e6e6b46a3a3a2d4034e25 /runsc/boot
parentb4a9f186872d6687f34e609a39aa10eb33cce1d2 (diff)
Fix runsc restore to be compatible with docker start --checkpoint ...
Change-Id: I02b30de13f1393df66edf8829fedbf32405d18f8 PiperOrigin-RevId: 246621192
Diffstat (limited to 'runsc/boot')
-rw-r--r--runsc/boot/config.go3
-rw-r--r--runsc/boot/controller.go21
-rw-r--r--runsc/boot/fs.go9
3 files changed, 21 insertions, 12 deletions
diff --git a/runsc/boot/config.go b/runsc/boot/config.go
index b6771de30..15f624f9b 100644
--- a/runsc/boot/config.go
+++ b/runsc/boot/config.go
@@ -213,6 +213,9 @@ type Config struct {
// ProfileEnable is set to prepare the sandbox to be profiled.
ProfileEnable bool
+ // RestoreFile is the path to the saved container image
+ RestoreFile string
+
// TestOnlyAllowRunAsCurrentUserWithoutChroot should only be used in
// tests. It allows runsc to start the sandbox process as the current
// user, and without chrooting the sandbox process. This can be
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go
index ab7c58838..86f06bff1 100644
--- a/runsc/boot/controller.go
+++ b/runsc/boot/controller.go
@@ -19,6 +19,7 @@ import (
"fmt"
"os"
"path"
+ "syscall"
specs "github.com/opencontainers/runtime-spec/specs-go"
"gvisor.googlesource.com/gvisor/pkg/control/server"
@@ -304,12 +305,17 @@ type RestoreOpts struct {
func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
log.Debugf("containerManager.Restore")
- var specFile, deviceFile *os.File
+ var specFile *os.File
+ deviceFD := -1
switch numFiles := len(o.FilePayload.Files); numFiles {
case 2:
- // The device file is donated to the platform, so don't Close
- // it here.
- deviceFile = o.FilePayload.Files[1]
+ var err error
+ // The device file is donated to the platform.
+ // Can't take ownership away from os.File. dup them to get a new FD.
+ deviceFD, err = syscall.Dup(int(o.FilePayload.Files[1].Fd()))
+ if err != nil {
+ return fmt.Errorf("failed to dup file: %v", err)
+ }
fallthrough
case 1:
specFile = o.FilePayload.Files[0]
@@ -320,11 +326,12 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
return fmt.Errorf("at most two files may be passed to Restore")
}
+ networkStack := cm.l.k.NetworkStack()
// Destroy the old kernel and create a new kernel.
cm.l.k.Pause()
cm.l.k.Destroy()
- p, err := createPlatform(cm.l.conf, int(deviceFile.Fd()))
+ p, err := createPlatform(cm.l.conf, deviceFD)
if err != nil {
return fmt.Errorf("creating platform: %v", err)
}
@@ -347,10 +354,6 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
fs.SetRestoreEnvironment(*renv)
// Prepare to load from the state file.
- networkStack, err := newEmptyNetworkStack(cm.l.conf, k)
- if err != nil {
- return fmt.Errorf("creating network: %v", err)
- }
if eps, ok := networkStack.(*epsocket.Stack); ok {
stack.StackFromEnv = eps.Stack // FIXME(b/36201077)
}
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go
index aeb1c52cc..1611dda2c 100644
--- a/runsc/boot/fs.go
+++ b/runsc/boot/fs.go
@@ -187,7 +187,7 @@ func compileMounts(spec *specs.Spec) []specs.Mount {
// createRootMount creates the root filesystem.
func createRootMount(ctx context.Context, spec *specs.Spec, conf *Config, fds *fdDispenser, mounts []specs.Mount) (*fs.Inode, error) {
// First construct the filesystem from the spec.Root.
- mf := fs.MountSourceFlags{ReadOnly: spec.Root.Readonly}
+ mf := fs.MountSourceFlags{ReadOnly: spec.Root.Readonly || conf.Overlay}
var (
rootInode *fs.Inode
@@ -419,7 +419,7 @@ func mountDevice(m specs.Mount) string {
// addRestoreMount adds a mount to the MountSources map used for restoring a
// checkpointed container.
func addRestoreMount(conf *Config, renv *fs.RestoreEnvironment, m specs.Mount, fds *fdDispenser) error {
- fsName, opts, _, err := getMountNameAndOptions(conf, m, fds)
+ fsName, opts, useOverlay, err := getMountNameAndOptions(conf, m, fds)
// Return the error or nil that corresponds to the default case in getMountNameAndOptions.
if err != nil {
@@ -436,6 +436,9 @@ func addRestoreMount(conf *Config, renv *fs.RestoreEnvironment, m specs.Mount, f
Flags: mountFlags(m.Options),
DataString: strings.Join(opts, ","),
}
+ if useOverlay {
+ newMount.Flags.ReadOnly = true
+ }
renv.MountSources[fsName] = append(renv.MountSources[fsName], newMount)
log.Infof("Added mount at %q: %+v", fsName, newMount)
return nil
@@ -453,7 +456,7 @@ func createRestoreEnvironment(spec *specs.Spec, conf *Config, fds *fdDispenser)
opts := p9MountOptions(fd, conf.FileAccess)
mf := fs.MountSourceFlags{}
- if spec.Root.Readonly {
+ if spec.Root.Readonly || conf.Overlay {
mf.ReadOnly = true
}