diff options
author | Andrei Vagin <avagin@gmail.com> | 2019-05-03 21:40:48 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-05-03 21:41:45 -0700 |
commit | bf0ac565d2873069799082ad7bc3e3c43acbc593 (patch) | |
tree | 398abb381e328568809e6e6b46a3a3a2d4034e25 /runsc/boot | |
parent | b4a9f186872d6687f34e609a39aa10eb33cce1d2 (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.go | 3 | ||||
-rw-r--r-- | runsc/boot/controller.go | 21 | ||||
-rw-r--r-- | runsc/boot/fs.go | 9 |
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 } |