From aa60541877a8a851524791a72ba3968e6764e137 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 8 Apr 2019 20:53:38 -0700 Subject: [PATCH 1/6] pkg/mount: MakeMount: minor optimization Current code in MakeMount parses /proc/self/mountinfo twice: first in call to Mounted(), then in call to Mount(). Use ForceMount() to eliminate such double parsing. Signed-off-by: Kir Kolyshkin --- pkg/mount/sharedsubtree_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/mount/sharedsubtree_linux.go b/pkg/mount/sharedsubtree_linux.go index 8a100f0bc8..5217dae3b2 100644 --- a/pkg/mount/sharedsubtree_linux.go +++ b/pkg/mount/sharedsubtree_linux.go @@ -59,7 +59,7 @@ func MakeMount(mnt string) error { return nil } - return Mount(mnt, mnt, "none", "bind") + return ForceMount(mnt, mnt, "none", "bind") } func ensureMountedAs(mountPoint, options string) error { From 80fce834ad4f73bcee261982485ff9ec42a7e897 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 2 Apr 2019 17:23:30 -0700 Subject: [PATCH 2/6] pkg/mount: Mount: minor optimization Eliminate double call to parseOptions() from Mount() Signed-off-by: Kir Kolyshkin --- pkg/mount/mount.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/mount/mount.go b/pkg/mount/mount.go index 4afd63c427..be0631c630 100644 --- a/pkg/mount/mount.go +++ b/pkg/mount/mount.go @@ -102,13 +102,13 @@ func Mounted(mountpoint string) (bool, error) { // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See // flags.go for supported option flags. func Mount(device, target, mType, options string) error { - flag, _ := parseOptions(options) + flag, data := parseOptions(options) if flag&REMOUNT != REMOUNT { if mounted, err := Mounted(target); err != nil || mounted { return err } } - return ForceMount(device, target, mType, options) + return mount(device, target, mType, uintptr(flag), data) } // ForceMount will mount a filesystem according to the specified configuration, From 4e65b17ac4e2792ae80c9415c68f9263c3d18db4 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 9 Apr 2019 11:46:26 -0700 Subject: [PATCH 3/6] daemon/mountVolumes: no need to specify fstype For bind mounts, fstype argument to mount(2) is ignored. Usual convention is either empty string or "none". Signed-off-by: Kir Kolyshkin --- daemon/bindmount_unix.go | 5 ----- daemon/volumes_unix.go | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 daemon/bindmount_unix.go diff --git a/daemon/bindmount_unix.go b/daemon/bindmount_unix.go deleted file mode 100644 index 028e300b06..0000000000 --- a/daemon/bindmount_unix.go +++ /dev/null @@ -1,5 +0,0 @@ -// +build linux freebsd - -package daemon // import "github.com/docker/docker/daemon" - -const bindMountType = "bind" diff --git a/daemon/volumes_unix.go b/daemon/volumes_unix.go index 5b47c46616..13e0a90194 100644 --- a/daemon/volumes_unix.go +++ b/daemon/volumes_unix.go @@ -142,7 +142,7 @@ func (daemon *Daemon) mountVolumes(container *container.Container) error { writeMode = "rw" } opts := strings.Join([]string{bindMode, writeMode}, ",") - if err := mount.Mount(m.Source, dest, bindMountType, opts); err != nil { + if err := mount.Mount(m.Source, dest, "", opts); err != nil { return err } From a6773f69f26bf93a5183e41f66c1d36817c5b768 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Wed, 3 Apr 2019 01:36:33 +0000 Subject: [PATCH 4/6] daemon/mountVolumes(): eliminate MakeRPrivate call It is sufficient to add "rprivate" to mount flags. Signed-off-by: Kir Kolyshkin --- daemon/volumes_unix.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/daemon/volumes_unix.go b/daemon/volumes_unix.go index 13e0a90194..3f4c5ffda1 100644 --- a/daemon/volumes_unix.go +++ b/daemon/volumes_unix.go @@ -141,10 +141,6 @@ func (daemon *Daemon) mountVolumes(container *container.Container) error { if m.Writable { writeMode = "rw" } - opts := strings.Join([]string{bindMode, writeMode}, ",") - if err := mount.Mount(m.Source, dest, "", opts); err != nil { - return err - } // mountVolumes() seems to be called for temporary mounts // outside the container. Soon these will be unmounted with @@ -154,8 +150,9 @@ func (daemon *Daemon) mountVolumes(container *container.Container) error { // then these unmounts will propagate and unmount original // mount as well. So make all these mounts rprivate. // Do not use propagation property of volume as that should - // apply only when mounting happen inside the container. - if err := mount.MakeRPrivate(dest); err != nil { + // apply only when mounting happens inside the container. + opts := strings.Join([]string{bindMode, writeMode, "rprivate"}, ",") + if err := mount.Mount(m.Source, dest, "", opts); err != nil { return err } } From ec248fe61d4209992ef3e0d5e7ab3ffcf7933fdd Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 9 Apr 2019 11:25:41 -0700 Subject: [PATCH 5/6] pkg/mount/Make*: optimize The only option we supply is either BIND or a mount propagation flag, so it makes sense to specify the flag value directly, rather than using parseOptions() every time. Signed-off-by: Kir Kolyshkin --- pkg/mount/sharedsubtree_linux.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/mount/sharedsubtree_linux.go b/pkg/mount/sharedsubtree_linux.go index 5217dae3b2..db3882874a 100644 --- a/pkg/mount/sharedsubtree_linux.go +++ b/pkg/mount/sharedsubtree_linux.go @@ -3,49 +3,49 @@ package mount // import "github.com/docker/docker/pkg/mount" // MakeShared ensures a mounted filesystem has the SHARED mount option enabled. // See the supported options in flags.go for further reference. func MakeShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "shared") + return ensureMountedAs(mountPoint, SHARED) } // MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled. // See the supported options in flags.go for further reference. func MakeRShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "rshared") + return ensureMountedAs(mountPoint, RSHARED) } // MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled. // See the supported options in flags.go for further reference. func MakePrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "private") + return ensureMountedAs(mountPoint, PRIVATE) } // MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option // enabled. See the supported options in flags.go for further reference. func MakeRPrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "rprivate") + return ensureMountedAs(mountPoint, RPRIVATE) } // MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled. // See the supported options in flags.go for further reference. func MakeSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "slave") + return ensureMountedAs(mountPoint, SLAVE) } // MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled. // See the supported options in flags.go for further reference. func MakeRSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "rslave") + return ensureMountedAs(mountPoint, RSLAVE) } // MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option // enabled. See the supported options in flags.go for further reference. func MakeUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "unbindable") + return ensureMountedAs(mountPoint, UNBINDABLE) } // MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount // option enabled. See the supported options in flags.go for further reference. func MakeRUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "runbindable") + return ensureMountedAs(mountPoint, RUNBINDABLE) } // MakeMount ensures that the file or directory given is a mount point, @@ -59,13 +59,13 @@ func MakeMount(mnt string) error { return nil } - return ForceMount(mnt, mnt, "none", "bind") + return mount(mnt, mnt, "none", uintptr(BIND), "") } -func ensureMountedAs(mountPoint, options string) error { - if err := MakeMount(mountPoint); err != nil { +func ensureMountedAs(mnt string, flags int) error { + if err := MakeMount(mnt); err != nil { return err } - return ForceMount("", mountPoint, "none", options) + return mount("", mnt, "none", uintptr(flags), "") } From 1cfdb2ffb8dc3daf2afca89627d52697f16e7077 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 9 Apr 2019 11:04:26 -0700 Subject: [PATCH 6/6] TestContainersAPICreateMountsCreate: minor optimization Don't use two-stage mount in TestContainersAPICreateMountsCreate(); apparently it was written before mount.Mount() could accept propagation flags. While at it, remove rw as this is the default. Signed-off-by: Kir Kolyshkin --- integration-cli/docker_api_containers_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 3318f9fab8..44924f5af4 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -2115,8 +2115,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *check.C) { assert.NilError(c, err) defer os.RemoveAll(tmpDir3) - c.Assert(mount.Mount(tmpDir3, tmpDir3, "none", "bind,rw"), checker.IsNil) - c.Assert(mount.ForceMount("", tmpDir3, "none", "shared"), checker.IsNil) + c.Assert(mount.Mount(tmpDir3, tmpDir3, "none", "bind,shared"), checker.IsNil) cases = append(cases, []testCase{ {