Merge component 'engine' from git@github.com:moby/moby master

This commit is contained in:
GordonTheTurtle
2018-03-08 17:07:06 +00:00
8 changed files with 85 additions and 49 deletions
@@ -2223,6 +2223,38 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error {
return err
}
func (devices *DeviceSet) unmountAndDeactivateAll(dir string) {
files, err := ioutil.ReadDir(dir)
if err != nil {
logrus.Warnf("devmapper: unmountAndDeactivate: %s", err)
return
}
for _, d := range files {
if !d.IsDir() {
continue
}
name := d.Name()
fullname := path.Join(dir, name)
// We use MNT_DETACH here in case it is still busy in some running
// container. This means it'll go away from the global scope directly,
// and the device will be released when that container dies.
if err := unix.Unmount(fullname, unix.MNT_DETACH); err != nil && err != unix.EINVAL {
logrus.Warnf("devmapper: Shutdown unmounting %s, error: %s", fullname, err)
}
if devInfo, err := devices.lookupDevice(name); err != nil {
logrus.Debugf("devmapper: Shutdown lookup device %s, error: %s", name, err)
} else {
if err := devices.deactivateDevice(devInfo); err != nil {
logrus.Debugf("devmapper: Shutdown deactivate %s, error: %s", devInfo.Hash, err)
}
}
}
}
// Shutdown shuts down the device by unmounting the root.
func (devices *DeviceSet) Shutdown(home string) error {
logrus.Debugf("devmapper: [deviceset %s] Shutdown()", devices.devicePrefix)
@@ -2244,45 +2276,7 @@ func (devices *DeviceSet) Shutdown(home string) error {
// will be killed and we will not get a chance to save deviceset
// metadata. Hence save this early before trying to deactivate devices.
devices.saveDeviceSetMetaData()
// ignore the error since it's just a best effort to not try to unmount something that's mounted
mounts, _ := mount.GetMounts()
mounted := make(map[string]bool, len(mounts))
for _, mnt := range mounts {
mounted[mnt.Mountpoint] = true
}
if err := filepath.Walk(path.Join(home, "mnt"), func(p string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
return nil
}
if mounted[p] {
// We use MNT_DETACH here in case it is still busy in some running
// container. This means it'll go away from the global scope directly,
// and the device will be released when that container dies.
if err := unix.Unmount(p, unix.MNT_DETACH); err != nil {
logrus.Debugf("devmapper: Shutdown unmounting %s, error: %s", p, err)
}
}
if devInfo, err := devices.lookupDevice(path.Base(p)); err != nil {
logrus.Debugf("devmapper: Shutdown lookup device %s, error: %s", path.Base(p), err)
} else {
if err := devices.deactivateDevice(devInfo); err != nil {
logrus.Debugf("devmapper: Shutdown deactivate %s , error: %s", devInfo.Hash, err)
}
}
return nil
}); err != nil && !os.IsNotExist(err) {
devices.Unlock()
return err
}
devices.unmountAndDeactivateAll(path.Join(home, "mnt"))
devices.Unlock()
info, _ := devices.lookupDeviceWithLock("")
@@ -16,6 +16,7 @@ import (
"github.com/docker/docker/pkg/locker"
"github.com/docker/docker/pkg/mount"
units "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@@ -121,12 +122,18 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
// Cleanup unmounts a device.
func (d *Driver) Cleanup() error {
err := d.DeviceSet.Shutdown(d.home)
umountErr := mount.RecursiveUnmount(d.home)
if err2 := mount.RecursiveUnmount(d.home); err == nil {
err = err2
// in case we have two errors, prefer the one from Shutdown()
if err != nil {
return err
}
return err
if umountErr != nil {
return errors.Wrapf(umountErr, "error unmounting %s", d.home)
}
return nil
}
// CreateReadWrite creates a layer that is writable for use as a container
@@ -14,10 +14,15 @@ install_containerd() {
(
if [ "$1" == "static" ]; then
export BUILDTAGS='static_build netgo'
export EXTRA_FLAGS='-buildmod pie'
export EXTRA_LDFLAGS='-extldflags "-fno-PIC -static"'
export BUILDTAGS='static_build netgo'
export EXTRA_FLAGS='-buildmode=pie'
export EXTRA_LDFLAGS='-extldflags "-fno-PIC -static"'
# Reset build flags to nothing if we want a dynbinary
if [ "$1" == "dynamic" ]; then
export BUILDTAGS=''
export EXTRA_FLAGS=''
export EXTRA_LDFLAGS=''
fi
make
@@ -23,6 +23,7 @@ install_proxy() {
install_proxy_dynamic() {
export PROXY_LDFLAGS="-linkmode=external" install_proxy
export BUILD_MODE="-buildmode=pie"
_install_proxy
}
@@ -31,7 +32,7 @@ _install_proxy() {
git clone https://github.com/docker/libnetwork.git "$GOPATH/src/github.com/docker/libnetwork"
cd "$GOPATH/src/github.com/docker/libnetwork"
git checkout -q "$LIBNETWORK_COMMIT"
go build -buildmode=pie -ldflags="$PROXY_LDFLAGS" -o ${PREFIX}/docker-proxy github.com/docker/libnetwork/cmd/proxy
go build $BUILD_MODE -ldflags="$PROXY_LDFLAGS" -o ${PREFIX}/docker-proxy github.com/docker/libnetwork/cmd/proxy
}
@@ -11,7 +11,12 @@ install_runc() {
git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc"
cd "$GOPATH/src/github.com/opencontainers/runc"
git checkout -q "$RUNC_COMMIT"
make BUILDTAGS="$RUNC_BUILDTAGS" $1
if [ -z "$1" ]; then
target=static
else
target="$1"
fi
make BUILDTAGS="$RUNC_BUILDTAGS" "$target"
mkdir -p ${PREFIX}
cp runc ${PREFIX}/docker-runc
}
@@ -25,6 +25,10 @@ func TestMountOptionsParsing(t *testing.T) {
}
func TestMounted(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("root required")
}
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)
@@ -76,6 +80,10 @@ func TestMounted(t *testing.T) {
}
func TestMountReadonly(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("root required")
}
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)
@@ -14,7 +14,7 @@ import (
func TestMount(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("not root tests would fail")
t.Skip("root required")
}
source, err := ioutil.TempDir("", "mount-test-source-")
@@ -12,6 +12,10 @@ import (
// nothing is propagated in or out
func TestSubtreePrivate(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("root required")
}
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)
@@ -110,6 +114,10 @@ func TestSubtreePrivate(t *testing.T) {
// Testing that when a target is a shared mount,
// then child mounts propagate to the source
func TestSubtreeShared(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("root required")
}
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)
@@ -178,6 +186,10 @@ func TestSubtreeShared(t *testing.T) {
// testing that mounts to a shared source show up in the slave target,
// and that mounts into a slave target do _not_ show up in the shared source
func TestSubtreeSharedSlave(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("root required")
}
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)
@@ -282,6 +294,10 @@ func TestSubtreeSharedSlave(t *testing.T) {
}
func TestSubtreeUnbindable(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("root required")
}
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)