1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #35316 from kolyshkin/facepalm

Fix honoring tmpfs-size for user /dev/shm mount
This commit is contained in:
Vincent Demeester 2017-11-14 11:13:59 +01:00 committed by GitHub
commit f70c715be0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 17 deletions

View file

@ -5,6 +5,13 @@ package daemon
import ( import (
"strings" "strings"
"testing" "testing"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/oci"
"github.com/docker/docker/pkg/idtools"
"github.com/stretchr/testify/assert"
) )
const mountsFixture = `142 78 0:38 / / rw,relatime - aufs none rw,si=573b861da0b3a05b,dio const mountsFixture = `142 78 0:38 / / rw,relatime - aufs none rw,si=573b861da0b3a05b,dio
@ -102,3 +109,51 @@ func TestNotCleanupMounts(t *testing.T) {
t.Fatal("Expected not to clean up /dev/shm") t.Fatal("Expected not to clean up /dev/shm")
} }
} }
// TestTmpfsDevShmSizeOverride checks that user-specified /dev/tmpfs mount
// size is not overriden by the default shmsize (that should only be used
// for default /dev/shm (as in "shareable" and "private" ipc modes).
// https://github.com/moby/moby/issues/35271
func TestTmpfsDevShmSizeOverride(t *testing.T) {
size := "777m"
mnt := "/dev/shm"
d := Daemon{
idMappings: &idtools.IDMappings{},
}
c := &container.Container{
HostConfig: &containertypes.HostConfig{
ShmSize: 48 * 1024, // size we should NOT end up with
},
}
ms := []container.Mount{
{
Source: "tmpfs",
Destination: mnt,
Data: "size=" + size,
},
}
// convert ms to spec
spec := oci.DefaultSpec()
err := setMounts(&d, &spec, c, ms)
assert.NoError(t, err)
// Check the resulting spec for the correct size
found := false
for _, m := range spec.Mounts {
if m.Destination == mnt {
for _, o := range m.Options {
if !strings.HasPrefix(o, "size=") {
continue
}
t.Logf("%+v\n", m.Options)
assert.Equal(t, "size="+size, o)
found = true
}
}
}
if !found {
t.Fatal("/dev/shm not found in spec, or size option missing")
}
}

View file

@ -538,23 +538,35 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c
userMounts[m.Destination] = struct{}{} userMounts[m.Destination] = struct{}{}
} }
// Filter out mounts from spec // Copy all mounts from spec to defaultMounts, except for
noIpc := c.HostConfig.IpcMode.IsNone() // - mounts overriden by a user supplied mount;
// Filter out mounts that are overridden by user supplied mounts // - all mounts under /dev if a user supplied /dev is present;
// - /dev/shm, in case IpcMode is none.
// While at it, also
// - set size for /dev/shm from shmsize.
var defaultMounts []specs.Mount var defaultMounts []specs.Mount
_, mountDev := userMounts["/dev"] _, mountDev := userMounts["/dev"]
for _, m := range s.Mounts { for _, m := range s.Mounts {
// filter out /dev/shm mount if case IpcMode is none if _, ok := userMounts[m.Destination]; ok {
if noIpc && m.Destination == "/dev/shm" { // filter out mount overridden by a user supplied mount
continue continue
} }
// filter out mount overridden by a user supplied mount if mountDev && strings.HasPrefix(m.Destination, "/dev/") {
if _, ok := userMounts[m.Destination]; !ok { // filter out everything under /dev if /dev is user-mounted
if mountDev && strings.HasPrefix(m.Destination, "/dev/") { continue
}
if m.Destination == "/dev/shm" {
if c.HostConfig.IpcMode.IsNone() {
// filter out /dev/shm for "none" IpcMode
continue continue
} }
defaultMounts = append(defaultMounts, m) // set size for /dev/shm mount from spec
sizeOpt := "size=" + strconv.FormatInt(c.HostConfig.ShmSize, 10)
m.Options = append(m.Options, sizeOpt)
} }
defaultMounts = append(defaultMounts, m)
} }
s.Mounts = defaultMounts s.Mounts = defaultMounts
@ -662,14 +674,6 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c
s.Linux.MaskedPaths = nil s.Linux.MaskedPaths = nil
} }
// Set size for /dev/shm mount that comes from spec (IpcMode: private only)
for i, m := range s.Mounts {
if m.Destination == "/dev/shm" {
sizeOpt := "size=" + strconv.FormatInt(c.HostConfig.ShmSize, 10)
s.Mounts[i].Options = append(s.Mounts[i].Options, sizeOpt)
}
}
// TODO: until a kernel/mount solution exists for handling remount in a user namespace, // TODO: until a kernel/mount solution exists for handling remount in a user namespace,
// we must clear the readonly flag for the cgroups mount (@mrunalp concurs) // we must clear the readonly flag for the cgroups mount (@mrunalp concurs)
if uidMap := daemon.idMappings.UIDs(); uidMap != nil || c.HostConfig.Privileged { if uidMap := daemon.idMappings.UIDs(); uidMap != nil || c.HostConfig.Privileged {