summaryrefslogtreecommitdiffhomepage
path: root/runsc
diff options
context:
space:
mode:
Diffstat (limited to 'runsc')
-rw-r--r--runsc/boot/controller.go5
-rw-r--r--runsc/boot/fs.go55
-rw-r--r--runsc/boot/loader.go25
3 files changed, 25 insertions, 60 deletions
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go
index d79aaff60..f1e4a9ba4 100644
--- a/runsc/boot/controller.go
+++ b/runsc/boot/controller.go
@@ -328,10 +328,8 @@ 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.
+ // Pause the kernel while we build a new one.
cm.l.k.Pause()
- cm.l.k.Destroy()
p, err := createPlatform(cm.l.conf, deviceFile)
if err != nil {
@@ -345,6 +343,7 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error {
return fmt.Errorf("creating memory file: %v", err)
}
k.SetMemoryFile(mf)
+ networkStack := cm.l.k.NetworkStack()
cm.l.k = k
// Set up the restore environment.
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go
index 7e95e1f41..98ce40991 100644
--- a/runsc/boot/fs.go
+++ b/runsc/boot/fs.go
@@ -34,12 +34,10 @@ import (
_ "gvisor.dev/gvisor/pkg/sentry/fs/tty"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/syserror"
"gvisor.dev/gvisor/runsc/specutils"
)
@@ -506,44 +504,16 @@ func newContainerMounter(spec *specs.Spec, cid string, goferFDs []int, k *kernel
}
}
-// setupFS is used to set up the file system for containers and amend
-// the procArgs accordingly. This is the main entry point for this rest of
-// functions in this file. procArgs are passed by reference and the FDMap field
-// is modified. It dups stdioFDs.
-func (c *containerMounter) setupFS(ctx context.Context, conf *Config, procArgs *kernel.CreateProcessArgs, creds *auth.Credentials) error {
- // Use root user to configure mounts. The current user might not have
- // permission to do so.
- rootProcArgs := kernel.CreateProcessArgs{
- WorkingDirectory: "/",
- Credentials: auth.NewRootCredentials(creds.UserNamespace),
- Umask: 0022,
- MaxSymlinkTraversals: linux.MaxSymlinkTraversals,
- PIDNamespace: procArgs.PIDNamespace,
- }
- rootCtx := rootProcArgs.NewContext(c.k)
-
- // If this is the root container, we also need to setup the root mount
- // namespace.
- rootMNS := c.k.RootMountNamespace()
- if rootMNS == nil {
- // Setup the root container.
- if err := c.setupRootContainer(ctx, rootCtx, conf, func(rootMNS *fs.MountNamespace) {
- // The callback to setupRootContainer inherits a
- // reference on the rootMNS, so we don't need to take
- // an additional reference here.
- procArgs.MountNamespace = rootMNS
- procArgs.Root = rootMNS.Root()
- c.k.SetRootMountNamespace(rootMNS)
- }); err != nil {
- return err
- }
- return c.checkDispenser()
- }
-
+// setupChildContainer is used to set up the file system for non-root containers
+// and amend the procArgs accordingly. This is the main entry point for this
+// rest of functions in this file. procArgs are passed by reference and the
+// FDMap field is modified. It dups stdioFDs.
+func (c *containerMounter) setupChildContainer(conf *Config, procArgs *kernel.CreateProcessArgs) error {
// Setup a child container.
log.Infof("Creating new process in child container.")
// Create a new root inode and mount namespace for the container.
+ rootCtx := c.k.SupervisorContext()
rootInode, err := c.createRootMount(rootCtx, conf)
if err != nil {
return fmt.Errorf("creating filesystem for container: %v", err)
@@ -552,14 +522,12 @@ func (c *containerMounter) setupFS(ctx context.Context, conf *Config, procArgs *
if err != nil {
return fmt.Errorf("creating new mount namespace for container: %v", err)
}
-
- // Set process root here, so 'rootCtx.Value(CtxRoot)' will return it.
- // This will also donate a reference to procArgs, as required.
procArgs.MountNamespace = mns
- procArgs.Root = mns.Root()
+ root := mns.Root()
+ defer root.DecRef()
// Mount all submounts.
- if err := c.mountSubmounts(rootCtx, conf, mns, procArgs.Root); err != nil {
+ if err := c.mountSubmounts(rootCtx, conf, mns, root); err != nil {
return err
}
return c.checkDispenser()
@@ -599,7 +567,10 @@ func (c *containerMounter) setupRootContainer(userCtx context.Context, rootCtx c
root := mns.Root()
defer root.DecRef()
- return c.mountSubmounts(rootCtx, conf, mns, root)
+ if err := c.mountSubmounts(rootCtx, conf, mns, root); err != nil {
+ return fmt.Errorf("mounting submounts: %v", err)
+ }
+ return c.checkDispenser()
}
// mountSharedMaster mounts the master of a volume that is shared among
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go
index 50cac0433..77e1aa456 100644
--- a/runsc/boot/loader.go
+++ b/runsc/boot/loader.go
@@ -527,12 +527,15 @@ func (l *Loader) run() error {
// cid for root container can be empty. Only subcontainers need it to set
// the mount location.
mntr := newContainerMounter(l.spec, "", l.goferFDs, l.k, l.mountHints)
- if err := mntr.setupFS(ctx, l.conf, &l.rootProcArgs, l.rootProcArgs.Credentials); err != nil {
+
+ // Setup the root container.
+ if err := mntr.setupRootContainer(ctx, ctx, l.conf, func(mns *fs.MountNamespace) {
+ l.rootProcArgs.MountNamespace = mns
+ }); err != nil {
return err
}
- rootCtx := l.rootProcArgs.NewContext(l.k)
- if err := setExecutablePath(rootCtx, &l.rootProcArgs); err != nil {
+ if err := setExecutablePath(ctx, &l.rootProcArgs); err != nil {
return err
}
@@ -546,7 +549,7 @@ func (l *Loader) run() error {
}
}
if !hasHomeEnvv {
- homeDir, err := getExecUserHome(rootCtx, l.rootProcArgs.MountNamespace, uint32(l.rootProcArgs.Credentials.RealKUID))
+ homeDir, err := getExecUserHome(ctx, l.rootProcArgs.MountNamespace, uint32(l.rootProcArgs.Credentials.RealKUID))
if err != nil {
return fmt.Errorf("error reading exec user: %v", err)
}
@@ -685,7 +688,7 @@ func (l *Loader) startContainer(spec *specs.Spec, conf *Config, cid string, file
}
mntr := newContainerMounter(spec, cid, goferFDs, l.k, l.mountHints)
- if err := mntr.setupFS(ctx, conf, &procArgs, creds); err != nil {
+ if err := mntr.setupChildContainer(conf, &procArgs); err != nil {
return fmt.Errorf("configuring container FS: %v", err)
}
@@ -756,22 +759,14 @@ func (l *Loader) executeAsync(args *control.ExecArgs) (kernel.ThreadID, error) {
return 0, fmt.Errorf("no such container: %q", args.ContainerID)
}
- // Get the container Root Dirent and MountNamespace from the Task.
+ // Get the container MountNamespace from the Task.
tg.Leader().WithMuLocked(func(t *kernel.Task) {
- // FSContext.RootDirectory() will take an extra ref for us.
- args.Root = t.FSContext().RootDirectory()
-
// task.MountNamespace() does not take a ref, so we must do so
// ourselves.
args.MountNamespace = t.MountNamespace()
args.MountNamespace.IncRef()
})
- defer func() {
- if args.Root != nil {
- args.Root.DecRef()
- }
- args.MountNamespace.DecRef()
- }()
+ defer args.MountNamespace.DecRef()
// Start the process.
proc := control.Proc{Kernel: l.k}