Merge pull request #8706 from sitano:restore_can_load

PiperOrigin-RevId: 518375542
This commit is contained in:
gVisor bot
2023-03-21 14:07:18 -07:00
2 changed files with 57 additions and 9 deletions
+1
View File
@@ -53,6 +53,7 @@ go_library(
deps = [
"//pkg/abi/linux",
"//pkg/atomicbitops",
"//pkg/cleanup",
"//pkg/coretag",
"//pkg/coverage",
"//pkg/cpuid",
+56 -9
View File
@@ -16,10 +16,13 @@ package cmd
import (
"context"
"os"
"path/filepath"
"github.com/google/subcommands"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/cleanup"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/runsc/cmd/util"
"gvisor.dev/gvisor/runsc/config"
"gvisor.dev/gvisor/runsc/container"
@@ -89,32 +92,76 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...any) subco
if bundleDir == "" {
bundleDir = getwdOrDie()
}
spec, err := specutils.ReadSpec(bundleDir, conf)
if err != nil {
return util.Errorf("reading spec: %v", err)
}
specutils.LogSpecDebug(spec, conf.OCISeccomp)
if r.imagePath == "" {
return util.Errorf("image-path flag must be provided")
}
var cu cleanup.Cleanup
defer cu.Clean()
conf.RestoreFile = filepath.Join(r.imagePath, checkpointFileName)
runArgs := container.Args{
ID: id,
Spec: spec,
Spec: nil,
BundleDir: bundleDir,
ConsoleSocket: r.consoleSocket,
PIDFile: r.pidFile,
UserLog: r.userLog,
Attached: !r.detach,
}
ws, err := container.Run(conf, runArgs)
log.Debugf("Restore container, cid: %s, rootDir: %q", id, conf.RootDir)
c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{})
if err != nil {
return util.Errorf("running container: %v", err)
if err != os.ErrNotExist {
return util.Errorf("loading container: %v", err)
}
log.Warningf("Container not found, creating new one, cid: %s, spec from: %s", id, bundleDir)
// Read the spec again here to ensure flag annotations from the spec are
// applied to "conf".
if runArgs.Spec, err = specutils.ReadSpec(bundleDir, conf); err != nil {
return util.Errorf("reading spec: %v", err)
}
specutils.LogSpecDebug(runArgs.Spec, conf.OCISeccomp)
if c, err = container.New(conf, runArgs); err != nil {
return util.Errorf("creating container: %v", err)
}
// Clean up partially created container if an error occurs.
// Any errors returned by Destroy() itself are ignored.
cu.Add(func() {
c.Destroy()
})
} else {
runArgs.Spec = c.Spec
}
log.Debugf("Restore: %v", conf.RestoreFile)
if err := c.Restore(runArgs.Spec, conf, conf.RestoreFile); err != nil {
return util.Errorf("starting container: %v", err)
}
// If we allocate a terminal, forward signals to the sandbox process.
// Otherwise, Ctrl+C will terminate this process and its children,
// including the terminal.
if c.Spec.Process.Terminal {
stopForwarding := c.ForwardSignals(0, true /* fgProcess */)
defer stopForwarding()
}
var ws unix.WaitStatus
if runArgs.Attached {
if ws, err = c.Wait(); err != nil {
return util.Errorf("running container: %v", err)
}
}
*waitStatus = ws
cu.Release()
return subcommands.ExitSuccess
}