Преглед изворни кода

devmapper: Move error detection to devmapper.go

This moves the EBUSY detection to devmapper.go, and then returns
a real ErrBusy that deviceset uses.

Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
Alexander Larsson пре 11 година
родитељ
комит
586a511cb5

+ 1 - 8
daemon/graphdriver/devmapper/deviceset.go

@@ -13,7 +13,6 @@ import (
 	"path"
 	"path/filepath"
 	"strconv"
-	"strings"
 	"sync"
 	"syscall"
 	"time"
@@ -62,7 +61,6 @@ type DeviceSet struct {
 	TransactionId    uint64
 	NewTransactionId uint64
 	nextFreeDevice   int
-	sawBusy          bool
 }
 
 type DiskUsage struct {
@@ -387,10 +385,6 @@ 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)
 }
 
@@ -710,12 +704,11 @@ func (devices *DeviceSet) removeDeviceAndWait(devname string) error {
 	var err error
 
 	for i := 0; i < 1000; i++ {
-		devices.sawBusy = false
 		err = removeDevice(devname)
 		if err == nil {
 			break
 		}
-		if !devices.sawBusy {
+		if err != ErrBusy {
 			return err
 		}
 

+ 7 - 0
daemon/graphdriver/devmapper/devmapper.go

@@ -62,6 +62,9 @@ var (
 	ErrInvalidAddNode         = errors.New("Invalide AddNoce type")
 	ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file")
 	ErrLoopbackSetCapacity    = errors.New("Unable set loopback capacity")
+	ErrBusy                   = errors.New("Device is Busy")
+
+	dmSawBusy bool
 )
 
 type (
@@ -512,7 +515,11 @@ func removeDevice(name string) error {
 	if task == nil {
 		return err
 	}
+	dmSawBusy = false
 	if err = task.Run(); err != nil {
+		if dmSawBusy {
+			return ErrBusy
+		}
 		return fmt.Errorf("Error running removeDevice")
 	}
 	return nil

+ 12 - 1
daemon/graphdriver/devmapper/devmapper_log.go

@@ -4,12 +4,23 @@ package devmapper
 
 import "C"
 
+import (
+	"strings"
+)
+
 // Due to the way cgo works this has to be in a separate file, as devmapper.go has
 // definitions in the cgo block, which is incompatible with using "//export"
 
 //export DevmapperLogCallback
 func DevmapperLogCallback(level C.int, file *C.char, line C.int, dm_errno_or_class C.int, message *C.char) {
+	msg := C.GoString(message)
+	if level < 7 {
+		if strings.Contains(msg, "busy") {
+			dmSawBusy = true
+		}
+	}
+
 	if dmLogger != nil {
-		dmLogger.log(int(level), C.GoString(file), int(line), int(dm_errno_or_class), C.GoString(message))
+		dmLogger.log(int(level), C.GoString(file), int(line), int(dm_errno_or_class), msg)
 	}
 }