diff --git a/components/engine/daemon/graphdriver/devmapper/driver.go b/components/engine/daemon/graphdriver/devmapper/driver.go index 53e05c3b78..e27f3c85cc 100644 --- a/components/engine/daemon/graphdriver/devmapper/driver.go +++ b/components/engine/daemon/graphdriver/devmapper/driver.go @@ -9,16 +9,15 @@ import ( "path" "strconv" - "github.com/sirupsen/logrus" - "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/pkg/containerfs" "github.com/docker/docker/pkg/devicemapper" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/locker" "github.com/docker/docker/pkg/mount" - "github.com/docker/docker/pkg/system" units "github.com/docker/go-units" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) func init() { @@ -145,7 +144,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { return d.DeviceSet.AddDevice(id, parent, storageOpt) } -// Remove removes a device with a given id, unmounts the filesystem. +// Remove removes a device with a given id, unmounts the filesystem, and removes the mount point. func (d *Driver) Remove(id string) error { d.locker.Lock(id) defer d.locker.Unlock(id) @@ -160,7 +159,21 @@ func (d *Driver) Remove(id string) error { if err := d.DeviceSet.DeleteDevice(id, false); err != nil { return fmt.Errorf("failed to remove device %s: %v", id, err) } - return system.EnsureRemoveAll(path.Join(d.home, "mnt", id)) + + // Most probably the mount point is already removed on Put() + // (see DeviceSet.UnmountDevice()), but just in case it was not + // let's try to remove it here as well, ignoring errors as + // an older kernel can return EBUSY if e.g. the mount was leaked + // to other mount namespaces. A failure to remove the container's + // mount point is not important and should not be treated + // as a failure to remove the container. + mp := path.Join(d.home, "mnt", id) + err := unix.Rmdir(mp) + if err != nil && !os.IsNotExist(err) { + logrus.WithField("storage-driver", "devicemapper").Warnf("unable to remove mount point %q: %s", mp, err) + } + + return nil } // Get mounts a device with given id into the root filesystem