浏览代码

Merge pull request #4794 from alexlarsson/dm-better-shutdown

devicemapper: Better/faster shutdown
Victor Vieux 11 年之前
父节点
当前提交
6643cc20fe
共有 1 个文件被更改,包括 17 次插入19 次删除
  1. 17 19
      runtime/graphdriver/devmapper/deviceset.go

+ 17 - 19
runtime/graphdriver/devmapper/deviceset.go

@@ -14,6 +14,7 @@ import (
 	"strconv"
 	"strings"
 	"sync"
+	"syscall"
 	"time"
 )
 
@@ -677,6 +678,12 @@ func (devices *DeviceSet) deactivateDevice(hash string) error {
 	utils.Debugf("[devmapper] deactivateDevice(%s)", hash)
 	defer utils.Debugf("[devmapper] deactivateDevice END")
 
+	// Wait for the unmount to be effective,
+	// by watching the value of Info.OpenCount for the device
+	if err := devices.waitClose(hash); err != nil {
+		utils.Errorf("Warning: error waiting for device %s to close: %s\n", hash, err)
+	}
+
 	info := devices.Devices[hash]
 	if info == nil {
 		return fmt.Errorf("Unknown device %s", hash)
@@ -799,24 +806,18 @@ func (devices *DeviceSet) Shutdown() error {
 	for _, info := range devices.Devices {
 		info.lock.Lock()
 		if info.mountCount > 0 {
-			if err := sysUnmount(info.mountPath, 0); err != nil {
+			// We use MNT_DETACH here in case it is still busy in some running
+			// container. This means it'll go away from the global scope directly,
+			// and the device will be released when that container dies.
+			if err := sysUnmount(info.mountPath, syscall.MNT_DETACH); err != nil {
 				utils.Debugf("Shutdown unmounting %s, error: %s\n", info.mountPath, err)
 			}
-		}
-		info.lock.Unlock()
-	}
-
-	for _, d := range devices.Devices {
-		d.lock.Lock()
 
-		if err := devices.waitClose(d.Hash); err != nil {
-			utils.Errorf("Warning: error waiting for device %s to unmount: %s\n", d.Hash, err)
-		}
-		if err := devices.deactivateDevice(d.Hash); err != nil {
-			utils.Debugf("Shutdown deactivate %s , error: %s\n", d.Hash, err)
+			if err := devices.deactivateDevice(info.Hash); err != nil {
+				utils.Debugf("Shutdown deactivate %s , error: %s\n", info.Hash, err)
+			}
 		}
-
-		d.lock.Unlock()
+		info.lock.Unlock()
 	}
 
 	if err := devices.deactivatePool(); err != nil {
@@ -920,14 +921,11 @@ func (devices *DeviceSet) UnmountDevice(hash string, mode UnmountMode) error {
 		return err
 	}
 	utils.Debugf("[devmapper] Unmount done")
-	// Wait for the unmount to be effective,
-	// by watching the value of Info.OpenCount for the device
-	if err := devices.waitClose(hash); err != nil {
+
+	if err := devices.deactivateDevice(hash); err != nil {
 		return err
 	}
 
-	devices.deactivateDevice(hash)
-
 	info.mountPath = ""
 
 	return nil