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 <alexl@redhat.com> (github: alexlarsson)
This commit is contained in:
Alexander Larsson 2014-02-05 21:37:53 +01:00
Родитель 7e25cd5891
Коммит 2c82fd93d8
1 изменённых файлов: 24 добавлений и 1 удалений

Просмотреть файл

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