diff --git a/runsc/boot/vfs.go b/runsc/boot/vfs.go index 1a1d64de9..bf64bc72c 100644 --- a/runsc/boot/vfs.go +++ b/runsc/boot/vfs.go @@ -253,9 +253,10 @@ func compileMounts(spec *specs.Spec, conf *config.Config) []specs.Mount { } // goferMountData creates a slice of gofer mount data. -func goferMountData(fd int, fa config.FileAccessType) []string { +func goferMountData(fd int, fa config.FileAccessType, dstPath string) []string { opts := []string{ "trans=fd", + "aname=" + dstPath, "rfdno=" + strconv.Itoa(fd), "wfdno=" + strconv.Itoa(fd), } @@ -401,7 +402,7 @@ func (c *containerMounter) mountAll(conf *config.Config, procArgs *kernel.Create // createMountNamespace creates the container's root mount and namespace. func (c *containerMounter) createMountNamespace(ctx context.Context, conf *config.Config, creds *auth.Credentials) (*vfs.MountNamespace, error) { fd := c.fds.remove() - data := goferMountData(fd, conf.FileAccess) + data := goferMountData(fd, conf.FileAccess, "/") // We can't check for overlayfs here because sandbox is chroot'ed and gofer // can only send mount options for specs.Mounts (specs.Root is missing @@ -711,7 +712,7 @@ func (c *containerMounter) getMountNameAndOptions(conf *config.Config, m *mountA // but unlikely to be correct in this context. return "", nil, false, fmt.Errorf("gofer mount requires a connection FD") } - data = goferMountData(m.fd, c.getMountAccessType(conf, m.mount)) + data = goferMountData(m.fd, c.getMountAccessType(conf, m.mount), m.mount.Destination) internalData = gofer.InternalFilesystemOptions{ UniqueID: m.mount.Destination, } diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index e9409bb80..a28d3a7c0 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -246,9 +246,8 @@ func newSocket(ioFD int) *unet.Socket { func (g *Gofer) serve(spec *specs.Spec, conf *config.Config, root string) subcommands.ExitStatus { type connectionConfig struct { - sock *unet.Socket - mountPath string - readonly bool + sock *unet.Socket + readonly bool } cfgs := make([]connectionConfig, 0, len(spec.Mounts)+1) server := fsgofer.NewLisafsServer(fsgofer.Config{ @@ -261,9 +260,8 @@ func (g *Gofer) serve(spec *specs.Spec, conf *config.Config, root string) subcom // Start with root mount, then add any other additional mount as needed. cfgs = append(cfgs, connectionConfig{ - sock: newSocket(g.ioFDs[0]), - mountPath: "/", // fsgofer process is always chroot()ed. So serve root. - readonly: spec.Root.Readonly || overlay2.RootMount, + sock: newSocket(g.ioFDs[0]), + readonly: spec.Root.Readonly || overlay2.RootMount, }) log.Infof("Serving %q mapped to %q on FD %d (ro: %t)", "/", root, g.ioFDs[0], cfgs[0].readonly) @@ -281,9 +279,8 @@ func (g *Gofer) serve(spec *specs.Spec, conf *config.Config, root string) subcom } cfgs = append(cfgs, connectionConfig{ - sock: newSocket(g.ioFDs[mountIdx]), - mountPath: m.Destination, - readonly: isReadonlyMount(m.Options) || overlay2.SubMounts, + sock: newSocket(g.ioFDs[mountIdx]), + readonly: isReadonlyMount(m.Options) || overlay2.SubMounts, }) log.Infof("Serving %q mapped on FD %d (ro: %t)", m.Destination, g.ioFDs[mountIdx], cfgs[mountIdx].readonly) @@ -296,7 +293,9 @@ func (g *Gofer) serve(spec *specs.Spec, conf *config.Config, root string) subcom cfgs = cfgs[:mountIdx] for _, cfg := range cfgs { - conn, err := server.CreateConnection(cfg.sock, cfg.mountPath, cfg.readonly) + // fsgofer process is always chroot()ed. So we can serve root. The gofer + // client should walk to the right mount point from the root. + conn, err := server.CreateConnection(cfg.sock, "/", cfg.readonly) if err != nil { util.Fatalf("starting connection on FD %d for gofer mount failed: %v", cfg.sock.FD(), err) }