Modified boot.go to allow for restores.
A file descriptor was added as a flag to boot so a state file can restore a container that was checkpointed. PiperOrigin-RevId: 201068699 Change-Id: I18e96069488ffa3add468861397f3877725544aa
This commit is contained in:
parent
7eaca1074b
commit
873ec0c414
|
@ -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",
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue