summaryrefslogtreecommitdiffhomepage
path: root/runsc/boot
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-09-11 13:08:36 -0700
committerShentubot <shentubot@google.com>2018-09-11 13:09:46 -0700
commit6cc9b311af3633d244f526abed50c0d3b0ce06a1 (patch)
tree923f589f98d323f17dd2a635c2744564de43f210 /runsc/boot
parentc44bc6612fc4554d0aa4e484a46cd1f6b6a7b5c5 (diff)
platform: Pass device fd into platform constructor.
We were previously openining the platform device (i.e. /dev/kvm) inside the platfrom constructor (i.e. kvm.New). This requires that we have RW access to the platform device when constructing the platform. However, now that the runsc sandbox process runs as user "nobody", it is not able to open the platform device. This CL changes the kvm constructor to take the platform device FD, rather than opening the device file itself. The device file is opened outside of the sandbox and passed to the sandbox process. PiperOrigin-RevId: 212505804 Change-Id: I427e1d9de5eb84c84f19d513356e1bb148a52910
Diffstat (limited to 'runsc/boot')
-rw-r--r--runsc/boot/controller.go24
-rw-r--r--runsc/boot/loader.go11
-rw-r--r--runsc/boot/loader_test.go2
3 files changed, 27 insertions, 10 deletions
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go
index fd5b7cc9e..257f275f9 100644
--- a/runsc/boot/controller.go
+++ b/runsc/boot/controller.go
@@ -17,6 +17,7 @@ package boot
import (
"errors"
"fmt"
+ "os"
"path"
specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -287,7 +288,8 @@ func (cm *containerManager) WaitForLoader(_, _ *struct{}) error {
// RestoreOpts contains options related to restoring a container's file system.
type RestoreOpts struct {
- // FilePayload contains the state file to be restored.
+ // FilePayload contains the state file to be restored, followed by the
+ // platform device file if necessary.
urpc.FilePayload
// SandboxID contains the ID of the sandbox.
@@ -300,16 +302,28 @@ type RestoreOpts struct {
// signal to start.
func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
log.Debugf("containerManager.Restore")
- if len(o.FilePayload.Files) != 1 {
- return fmt.Errorf("exactly one file must be provided")
+
+ var specFile, deviceFile *os.File
+ 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]
+ fallthrough
+ case 1:
+ specFile = o.FilePayload.Files[0]
+ defer specFile.Close()
+ case 0:
+ return fmt.Errorf("at least one file must be passed to Restore")
+ default:
+ return fmt.Errorf("at most two files may be passed to Restore")
}
- defer o.FilePayload.Files[0].Close()
// Destroy the old kernel and create a new kernel.
cm.l.k.Pause()
cm.l.k.Destroy()
- p, err := createPlatform(cm.l.conf)
+ p, err := createPlatform(cm.l.conf, int(deviceFile.Fd()))
if err != nil {
return fmt.Errorf("error creating platform: %v", err)
}
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go
index 994b3d2e2..30d22b9c6 100644
--- a/runsc/boot/loader.go
+++ b/runsc/boot/loader.go
@@ -122,9 +122,9 @@ func init() {
// New initializes a new kernel loader configured by spec.
// New also handles setting up a kernel for restoring a container.
-func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console bool) (*Loader, error) {
+func New(spec *specs.Spec, conf *Config, controllerFD, deviceFD int, ioFDs []int, console bool) (*Loader, error) {
// Create kernel and platform.
- p, err := createPlatform(conf)
+ p, err := createPlatform(conf, deviceFD)
if err != nil {
return nil, fmt.Errorf("error creating platform: %v", err)
}
@@ -301,14 +301,17 @@ func (l *Loader) Destroy() {
l.watchdog.Stop()
}
-func createPlatform(conf *Config) (platform.Platform, error) {
+func createPlatform(conf *Config, deviceFD int) (platform.Platform, error) {
switch conf.Platform {
case PlatformPtrace:
log.Infof("Platform: ptrace")
return ptrace.New()
case PlatformKVM:
log.Infof("Platform: kvm")
- return kvm.New()
+ if deviceFD < 0 {
+ return nil, fmt.Errorf("kvm device fd must be provided")
+ }
+ return kvm.New(os.NewFile(uintptr(deviceFD), "kvm device"))
default:
return nil, fmt.Errorf("invalid platform %v", conf.Platform)
}
diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go
index d6bfe9ff1..9398292ff 100644
--- a/runsc/boot/loader_test.go
+++ b/runsc/boot/loader_test.go
@@ -101,7 +101,7 @@ func createLoader() (*Loader, func(), error) {
return nil, nil, err
}
- l, err := New(spec, conf, fd, []int{sandEnd}, false)
+ l, err := New(spec, conf, fd, -1 /* device fd */, []int{sandEnd}, false)
if err != nil {
cleanup()
return nil, nil, err