From 2c82fd93d8a01cc1f53fe861378e6d2dca0486c6 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 5 Feb 2014 21:37:53 +0100 Subject: [PATCH] devmapper: Handle EBUSY while removing For some reason we seem to get transient EBUSY when removing thinp devices, which prohibit removing containers. When this happens we retry a few times which seems to fix the issue for me. Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- graphdriver/devmapper/deviceset.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/graphdriver/devmapper/deviceset.go b/graphdriver/devmapper/deviceset.go index 4955fb5cf0..3dedfd75b5 100644 --- a/graphdriver/devmapper/deviceset.go +++ b/graphdriver/devmapper/deviceset.go @@ -12,6 +12,7 @@ import ( "path" "path/filepath" "strconv" + "strings" "sync" "time" ) @@ -52,6 +53,7 @@ type DeviceSet struct { TransactionId uint64 NewTransactionId uint64 nextFreeDevice int + sawBusy bool } type DiskUsage struct { @@ -371,6 +373,10 @@ func (devices *DeviceSet) log(level int, file string, line int, dmError int, mes return // Ignore _LOG_DEBUG } + if strings.Contains(message, "busy") { + devices.sawBusy = true + } + utils.Debugf("libdevmapper(%d): %s:%d (%d) %s", level, file, line, dmError, message) } @@ -660,9 +666,26 @@ func (devices *DeviceSet) deactivateDevice(hash string) error { // Issues the underlying dm remove operation and then waits // for it to finish. func (devices *DeviceSet) removeDeviceAndWait(devname string) error { - if err := removeDevice(devname); err != nil { + var err error + + for i := 0; i < 10; i++ { + devices.sawBusy = false + err = removeDevice(devname) + if err == nil { + break + } + if !devices.sawBusy { + return err + } + + // If we see EBUSY it may be a transient error, + // sleep a bit a retry a few times. + time.Sleep(5 * time.Millisecond) + } + if err != nil { return err } + if err := devices.waitRemove(devname); err != nil { return err }