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 /runsc/cmd/gofer.go | |
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 'runsc/cmd/gofer.go')
-rw-r--r-- | runsc/cmd/gofer.go | 36 |
1 files changed, 12 insertions, 24 deletions
diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index 55315c0e8..ed4b1d29c 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -16,7 +16,6 @@ package cmd import ( "os" - "sync" "syscall" "context" @@ -25,7 +24,6 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/p9" - "gvisor.googlesource.com/gvisor/pkg/unet" "gvisor.googlesource.com/gvisor/runsc/fsgofer" "gvisor.googlesource.com/gvisor/runsc/specutils" ) @@ -36,6 +34,10 @@ type Gofer struct { bundleDir string ioFDs intFlags applyCaps bool + + // controllerFD is the file descriptor of a stream socket for the + // control server that is donated to this process. + controllerFD int } // Name implements subcommands.Command. @@ -58,11 +60,12 @@ func (g *Gofer) SetFlags(f *flag.FlagSet) { f.StringVar(&g.bundleDir, "bundle", "", "path to the root of the bundle directory, defaults to the current directory") f.Var(&g.ioFDs, "io-fds", "list of FDs to connect 9P servers. They must follow this order: root first, then mounts as defined in the spec") f.BoolVar(&g.applyCaps, "apply-caps", true, "if true, apply capabilities to restrict what the Gofer process can do") + f.IntVar(&g.controllerFD, "controller-fd", -1, "required FD of a stream socket for the control server that must be donated to this process") } // Execute implements subcommands.Command. func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { - if g.bundleDir == "" || len(g.ioFDs) < 1 { + if g.bundleDir == "" || len(g.ioFDs) < 1 || g.controllerFD == -1 { f.Usage() return subcommands.ExitUsageError } @@ -134,29 +137,14 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) Fatalf("Too many FDs passed for mounts. mounts: %d, FDs: %d", mountIdx, len(g.ioFDs)) } - runServers(ats, g.ioFDs) - return subcommands.ExitSuccess -} + ctrl, err := fsgofer.NewController(g.controllerFD, g.bundleDir) -func runServers(ats []p9.Attacher, ioFDs []int) { - // Run the loops and wait for all to exit. - var wg sync.WaitGroup - for i, ioFD := range ioFDs { - wg.Add(1) - go func(ioFD int, at p9.Attacher) { - socket, err := unet.NewSocket(ioFD) - if err != nil { - Fatalf("err creating server on FD %d: %v", ioFD, err) - } - s := p9.NewServer(at) - if err := s.Handle(socket); err != nil { - Fatalf("P9 server returned error. Gofer is shutting down. FD: %d, err: %v", ioFD, err) - } - wg.Done() - }(ioFD, ats[i]) + if err := ctrl.Serve(ats, g.ioFDs); err != nil { + Fatalf("Failed to serve via P9: %v", err) } - wg.Wait() - log.Infof("All 9P servers exited.") + ctrl.Wait() + + return subcommands.ExitSuccess } func isReadonlyMount(opts []string) bool { |