mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #35467 from kolyshkin/dup-mnt
Fix "duplicate mount point" when --tmpfs /dev/shm is used
This commit is contained in:
commit
d032264e13
2 changed files with 68 additions and 10 deletions
|
@ -65,12 +65,11 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
if _, err := os.Stat(container.ResolvConfPath); err != nil {
|
||||
logrus.Warnf("ResolvConfPath set to %q, but can't stat this filename (err = %v); skipping", container.ResolvConfPath, err)
|
||||
} else {
|
||||
if !container.HasMountFor("/etc/resolv.conf") {
|
||||
label.Relabel(container.ResolvConfPath, container.MountLabel, shared)
|
||||
}
|
||||
writable := !container.HostConfig.ReadonlyRootfs
|
||||
if m, exists := container.MountPoints["/etc/resolv.conf"]; exists {
|
||||
writable = m.RW
|
||||
} else {
|
||||
label.Relabel(container.ResolvConfPath, container.MountLabel, shared)
|
||||
}
|
||||
mounts = append(mounts, Mount{
|
||||
Source: container.ResolvConfPath,
|
||||
|
@ -84,12 +83,11 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
if _, err := os.Stat(container.HostnamePath); err != nil {
|
||||
logrus.Warnf("HostnamePath set to %q, but can't stat this filename (err = %v); skipping", container.HostnamePath, err)
|
||||
} else {
|
||||
if !container.HasMountFor("/etc/hostname") {
|
||||
label.Relabel(container.HostnamePath, container.MountLabel, shared)
|
||||
}
|
||||
writable := !container.HostConfig.ReadonlyRootfs
|
||||
if m, exists := container.MountPoints["/etc/hostname"]; exists {
|
||||
writable = m.RW
|
||||
} else {
|
||||
label.Relabel(container.HostnamePath, container.MountLabel, shared)
|
||||
}
|
||||
mounts = append(mounts, Mount{
|
||||
Source: container.HostnamePath,
|
||||
|
@ -103,12 +101,11 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
if _, err := os.Stat(container.HostsPath); err != nil {
|
||||
logrus.Warnf("HostsPath set to %q, but can't stat this filename (err = %v); skipping", container.HostsPath, err)
|
||||
} else {
|
||||
if !container.HasMountFor("/etc/hosts") {
|
||||
label.Relabel(container.HostsPath, container.MountLabel, shared)
|
||||
}
|
||||
writable := !container.HostConfig.ReadonlyRootfs
|
||||
if m, exists := container.MountPoints["/etc/hosts"]; exists {
|
||||
writable = m.RW
|
||||
} else {
|
||||
label.Relabel(container.HostsPath, container.MountLabel, shared)
|
||||
}
|
||||
mounts = append(mounts, Mount{
|
||||
Source: container.HostsPath,
|
||||
|
@ -160,7 +157,18 @@ func (container *Container) ShmResourcePath() (string, error) {
|
|||
// HasMountFor checks if path is a mountpoint
|
||||
func (container *Container) HasMountFor(path string) bool {
|
||||
_, exists := container.MountPoints[path]
|
||||
return exists
|
||||
if exists {
|
||||
return true
|
||||
}
|
||||
|
||||
// Also search among the tmpfs mounts
|
||||
for dest := range container.HostConfig.Tmpfs {
|
||||
if dest == path {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// UnmountIpcMount uses the provided unmount function to unmount shm if it was mounted
|
||||
|
|
50
daemon/oci_linux_test.go
Normal file
50
daemon/oci_linux_test.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/docker/docker/oci"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestTmpfsDevShmNoDupMount checks that a user-specified /dev/shm tmpfs
|
||||
// mount (as in "docker run --tmpfs /dev/shm:rw,size=NNN") does not result
|
||||
// in "Duplicate mount point" error from the engine.
|
||||
// https://github.com/moby/moby/issues/35455
|
||||
func TestTmpfsDevShmNoDupMount(t *testing.T) {
|
||||
d := Daemon{
|
||||
// some empty structs to avoid getting a panic
|
||||
// caused by a null pointer dereference
|
||||
idMappings: &idtools.IDMappings{},
|
||||
configStore: &config.Config{},
|
||||
}
|
||||
c := &container.Container{
|
||||
ShmPath: "foobar", // non-empty, for c.IpcMounts() to work
|
||||
HostConfig: &containertypes.HostConfig{
|
||||
IpcMode: containertypes.IpcMode("shareable"), // default mode
|
||||
// --tmpfs /dev/shm:rw,exec,size=NNN
|
||||
Tmpfs: map[string]string{
|
||||
"/dev/shm": "rw,exec,size=1g",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Mimick the code flow of daemon.createSpec(), enough to reproduce the issue
|
||||
ms, err := d.setupMounts(c)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ms = append(ms, c.IpcMounts()...)
|
||||
|
||||
tmpfsMounts, err := c.TmpfsMounts()
|
||||
assert.NoError(t, err)
|
||||
ms = append(ms, tmpfsMounts...)
|
||||
|
||||
s := oci.DefaultSpec()
|
||||
err = setMounts(&d, &s, c, ms)
|
||||
assert.NoError(t, err)
|
||||
}
|
Loading…
Add table
Reference in a new issue