Use mount hints to determine FileAccessType

PiperOrigin-RevId: 282401165
This commit is contained in:
Fabricio Voznika
2019-11-25 11:43:05 -08:00
committed by gVisor bot
parent a5f7b82036
commit 97d2c9a94e
2 changed files with 74 additions and 2 deletions
+16 -2
View File
@@ -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.
+58
View File
@@ -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)
}
})
}
}