diff options
author | Kevin Krakauer <krakauer@google.com> | 2018-08-15 16:24:07 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-08-15 16:25:22 -0700 |
commit | 635b0c45933cd841298b0c21a513a9169e849594 (patch) | |
tree | 058bae2ead9f7f182baaf3491580b5a419cb6c94 /pkg | |
parent | 2033f61aae6ff1b3e613d7bb9e9da273791a5176 (diff) |
runsc fsgofer: Support dynamic serving of filesystems.
When multiple containers run inside a sentry, each container has its own root
filesystem and set of mounts. Containers are also added after sentry boot rather
than all configured and known at boot time.
The fsgofer needs to be able to serve the root filesystem of each container.
Thus, it must be possible to add filesystems after the fsgofer has already
started.
This change:
* Creates a URPC endpoint within the gofer process that listens for requests to
serve new content.
* Enables the sentry, when starting a new container, to add the new container's
filesystem.
* Mounts those new filesystems at separate roots within the sentry.
PiperOrigin-RevId: 208903248
Change-Id: Ifa91ec9c8caf5f2f0a9eead83c4a57090ce92068
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/sentry/kernel/kernel.go | 14 | ||||
-rw-r--r-- | pkg/urpc/urpc.go | 10 |
2 files changed, 23 insertions, 1 deletions
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 419a1d473..cb43fdcdc 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -504,6 +504,14 @@ type CreateProcessArgs struct { // IPCNamespace is the initial IPC namespace. IPCNamespace *IPCNamespace + + // Root optionally contains the dirent that serves as the root for the + // process. If nil, the mount namespace's root is used as the process' + // root. + // + // Anyone setting Root must donate a reference (i.e. increment it) to + // keep it alive until it is decremented by CreateProcess. + Root *fs.Dirent } // NewContext returns a context.Context that represents the task that will be @@ -581,8 +589,12 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, error) { ctx := args.NewContext(k) // Grab the root directory. - root := fs.RootFromContext(ctx) + root := args.Root + if root == nil { + root = fs.RootFromContext(ctx) + } defer root.DecRef() + args.Root = nil // Grab the working directory. wd := root // Default. diff --git a/pkg/urpc/urpc.go b/pkg/urpc/urpc.go index af620b704..1ec06dd4c 100644 --- a/pkg/urpc/urpc.go +++ b/pkg/urpc/urpc.go @@ -63,6 +63,10 @@ func (r RemoteError) Error() string { // file as a result of an RPC. These are not actually serialized, rather they // are sent via an accompanying SCM_RIGHTS message (plumbed through the unet // package). +// +// When embedding a FilePayload in an argument struct, the argument type _must_ +// be a pointer to the struct rather than the struct type itself. This is +// because the urpc package defines pointer methods on FilePayload. type FilePayload struct { Files []*os.File `json:"-"` } @@ -552,6 +556,12 @@ func (c *Client) Call(method string, arg interface{}, result interface{}) error c.mu.Lock() defer c.mu.Unlock() + // If arg is a FilePayload, not a *FilePayload, files won't actually be + // sent, so error out. + if _, ok := arg.(FilePayload); ok { + return fmt.Errorf("argument is a FilePayload, but should be a *FilePayload") + } + // Are there files to send? var fs []*os.File if fp, ok := arg.(filePayloader); ok { |