summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--runsc/boot/BUILD1
-rw-r--r--runsc/boot/loader.go46
-rw-r--r--runsc/boot/loader_test.go2
-rw-r--r--runsc/cmd/boot.go6
4 files changed, 38 insertions, 17 deletions
diff --git a/runsc/boot/BUILD b/runsc/boot/BUILD
index 1a81acde5..8b3b09a22 100644
--- a/runsc/boot/BUILD
+++ b/runsc/boot/BUILD
@@ -51,6 +51,7 @@ go_library(
"//pkg/sentry/socket/netlink",
"//pkg/sentry/socket/netlink/route",
"//pkg/sentry/socket/unix",
+ "//pkg/sentry/state",
"//pkg/sentry/strace",
"//pkg/sentry/syscalls/linux",
"//pkg/sentry/time",
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go
index 89300a953..526e8f8bb 100644
--- a/runsc/boot/loader.go
+++ b/runsc/boot/loader.go
@@ -18,6 +18,7 @@ package boot
import (
"fmt"
"math/rand"
+ "os"
"runtime"
"sync/atomic"
"syscall"
@@ -35,6 +36,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/platform/kvm"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform/ptrace"
"gvisor.googlesource.com/gvisor/pkg/sentry/sighandling"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/state"
slinux "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux"
"gvisor.googlesource.com/gvisor/pkg/sentry/time"
"gvisor.googlesource.com/gvisor/pkg/sentry/watchdog"
@@ -90,7 +92,7 @@ func init() {
}
// New initializes a new kernel loader configured by spec.
-func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console bool) (*Loader, error) {
+func New(spec *specs.Spec, conf *Config, controllerFD, restoreFD int, ioFDs []int, console bool) (*Loader, error) {
// Create kernel and platform.
p, err := createPlatform(conf)
if err != nil {
@@ -165,20 +167,34 @@ func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console
// Run().
networkStack := newEmptyNetworkStack(conf, k)
- // Initiate the Kernel object, which is required by the Context passed
- // to createVFS in order to mount (among other things) procfs.
- if err = k.Init(kernel.InitKernelArgs{
- FeatureSet: cpuid.HostFeatureSet(),
- Timekeeper: tk,
- RootUserNamespace: creds.UserNamespace,
- NetworkStack: networkStack,
- // TODO: use number of logical processors from cgroups.
- ApplicationCores: uint(runtime.NumCPU()),
- Vdso: vdso,
- RootUTSNamespace: utsns,
- RootIPCNamespace: ipcns,
- }); err != nil {
- return nil, fmt.Errorf("error initializing kernel: %v", err)
+ // Check if we need to restore the kernel
+ if restoreFD != -1 {
+ restoreFile := os.NewFile(uintptr(restoreFD), "restore_file")
+ defer restoreFile.Close()
+
+ // Load the state.
+ loadOpts := state.LoadOpts{
+ Source: restoreFile,
+ }
+ if err := loadOpts.Load(k, p, networkStack); err != nil {
+ return nil, err
+ }
+ } else {
+ // Initiate the Kernel object, which is required by the Context passed
+ // to createVFS in order to mount (among other things) procfs.
+ if err = k.Init(kernel.InitKernelArgs{
+ FeatureSet: cpuid.HostFeatureSet(),
+ Timekeeper: tk,
+ RootUserNamespace: creds.UserNamespace,
+ NetworkStack: networkStack,
+ // TODO: use number of logical processors from cgroups.
+ ApplicationCores: uint(runtime.NumCPU()),
+ Vdso: vdso,
+ RootUTSNamespace: utsns,
+ RootIPCNamespace: ipcns,
+ }); err != nil {
+ return nil, fmt.Errorf("error initializing kernel: %v", err)
+ }
}
// Turn on packet logging if enabled.
diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go
index a7f59f775..dab7ad0c5 100644
--- a/runsc/boot/loader_test.go
+++ b/runsc/boot/loader_test.go
@@ -59,7 +59,7 @@ func createLoader() (*Loader, error) {
FileAccess: FileAccessDirect,
DisableSeccomp: true,
}
- return New(testSpec(), conf, fd, nil, false)
+ return New(testSpec(), conf, fd, -1, nil, false)
}
// TestRun runs a simple application in a sandbox and checks that it succeeds.
diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go
index 34dd8b3c0..86f597c09 100644
--- a/runsc/cmd/boot.go
+++ b/runsc/cmd/boot.go
@@ -48,6 +48,9 @@ type Boot struct {
// applyCaps determines if capabilities defined in the spec should be applied
// to the process.
applyCaps bool
+
+ // restoreFD is the file descriptor to the state file to be restored.
+ restoreFD int
}
// Name implements subcommands.Command.Name.
@@ -72,6 +75,7 @@ func (b *Boot) SetFlags(f *flag.FlagSet) {
f.Var(&b.ioFDs, "io-fds", "list of FDs to connect 9P clients. They must follow this order: root first, then mounts as defined in the spec")
f.BoolVar(&b.console, "console", false, "set to true if the sandbox should allow terminal ioctl(2) syscalls")
f.BoolVar(&b.applyCaps, "apply-caps", false, "if true, apply capabilities defined in the spec to the process")
+ f.IntVar(&b.restoreFD, "restore-fd", -1, "FD of the state file to be restored")
}
// Execute implements subcommands.Command.Execute. It starts a sandbox in a
@@ -127,7 +131,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
}
// Create the loader.
- l, err := boot.New(spec, conf, b.controllerFD, b.ioFDs.GetArray(), b.console)
+ l, err := boot.New(spec, conf, b.controllerFD, b.restoreFD, b.ioFDs.GetArray(), b.console)
if err != nil {
Fatalf("error creating loader: %v", err)
}