Merge component 'engine' from git@github.com:moby/moby master
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user