1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

devmapper/Remove(): use Rmdir, ignore errors

1. Replace EnsureRemoveAll() with Rmdir(), as here we are removing
   the container's mount point, which is already properly unmounted
   and is therefore an empty directory.

2. Ignore the Rmdir() error (but log it unless it's ENOENT). This
   is a mount point, currently unmounted (i.e. an empty directory),
   and an older kernel can return EBUSY if e.g. the mount was
   leaked to other mount namespaces.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin 2018-02-27 19:02:05 -08:00
parent a1afe38e52
commit 732dd9b848

View file

@ -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