From 97d2c9a94e802bcb450e50816a913dfc18afc0e3 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Mon, 25 Nov 2019 11:41:39 -0800 Subject: [PATCH] Use mount hints to determine FileAccessType PiperOrigin-RevId: 282401165 --- runsc/boot/fs.go | 18 ++++++++++++-- runsc/boot/fs_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 76036c147..bc9ffaf81 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -465,6 +465,13 @@ func (m *mountHint) checkCompatible(mount specs.Mount) error { return nil } +func (m *mountHint) fileAccessType() FileAccessType { + if m.share == container { + return FileAccessExclusive + } + return FileAccessShared +} + func filterUnsupportedOptions(mount specs.Mount) []string { rv := make([]string, 0, len(mount.Options)) for _, o := range mount.Options { @@ -764,8 +771,7 @@ func (c *containerMounter) getMountNameAndOptions(conf *Config, m specs.Mount) ( case bind: fd := c.fds.remove() fsName = "9p" - // Non-root bind mounts are always shared. - opts = p9MountOptions(fd, FileAccessShared) + opts = p9MountOptions(fd, c.getMountAccessType(m)) // If configured, add overlay to all writable mounts. useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly @@ -778,6 +784,14 @@ func (c *containerMounter) getMountNameAndOptions(conf *Config, m specs.Mount) ( return fsName, opts, useOverlay, nil } +func (c *containerMounter) getMountAccessType(mount specs.Mount) FileAccessType { + if hint := c.hints.findMount(mount); hint != nil { + return hint.fileAccessType() + } + // Non-root bind mounts are always shared if no hints were provided. + return FileAccessShared +} + // mountSubmount mounts volumes inside the container's root. Because mounts may // be readonly, a lower ramfs overlay is added to create the mount point dir. // Another overlay is added with tmpfs on top if Config.Overlay is true. diff --git a/runsc/boot/fs_test.go b/runsc/boot/fs_test.go index 49ab34b33..0396a4cfb 100644 --- a/runsc/boot/fs_test.go +++ b/runsc/boot/fs_test.go @@ -191,3 +191,61 @@ func TestPodMountHintsErrors(t *testing.T) { }) } } + +func TestGetMountAccessType(t *testing.T) { + const source = "foo" + for _, tst := range []struct { + name string + annotations map[string]string + want FileAccessType + }{ + { + name: "container=exclusive", + annotations: map[string]string{ + path.Join(MountPrefix, "mount1", "source"): source, + path.Join(MountPrefix, "mount1", "type"): "bind", + path.Join(MountPrefix, "mount1", "share"): "container", + }, + want: FileAccessExclusive, + }, + { + name: "pod=shared", + annotations: map[string]string{ + path.Join(MountPrefix, "mount1", "source"): source, + path.Join(MountPrefix, "mount1", "type"): "bind", + path.Join(MountPrefix, "mount1", "share"): "pod", + }, + want: FileAccessShared, + }, + { + name: "shared=shared", + annotations: map[string]string{ + path.Join(MountPrefix, "mount1", "source"): source, + path.Join(MountPrefix, "mount1", "type"): "bind", + path.Join(MountPrefix, "mount1", "share"): "shared", + }, + want: FileAccessShared, + }, + { + name: "default=shared", + annotations: map[string]string{ + path.Join(MountPrefix, "mount1", "source"): source + "mismatch", + path.Join(MountPrefix, "mount1", "type"): "bind", + path.Join(MountPrefix, "mount1", "share"): "container", + }, + want: FileAccessShared, + }, + } { + t.Run(tst.name, func(t *testing.T) { + spec := &specs.Spec{Annotations: tst.annotations} + podHints, err := newPodMountHints(spec) + if err != nil { + t.Fatalf("newPodMountHints failed: %v", err) + } + mounter := containerMounter{hints: podHints} + if got := mounter.getMountAccessType(specs.Mount{Source: source}); got != tst.want { + t.Errorf("getMountAccessType(), want: %v, got: %v", tst.want, got) + } + }) + } +}