浏览代码

deviceset: Cleanup device sets on test end

We unmount all mounts and deactivate all device mapper devices to
make sure we're left with no leftovers after the test.
Alexander Larsson 11 年之前
父节点
当前提交
c6e8813c97
共有 4 个文件被更改,包括 63 次插入5 次删除
  1. 5 0
      deviceset.go
  2. 50 4
      devmapper/deviceset_devmapper.go
  3. 7 0
      runtime_test.go
  4. 1 1
      z_final_test.go

+ 5 - 0
deviceset.go

@@ -9,6 +9,7 @@ type DeviceSet interface {
 	UnmountDevice(hash, path string) error
 	HasDevice(hash string) bool
 	HasInitializedDevice(hash string) bool
+	Shutdown() error
 }
 
 type DeviceSetWrapper struct {
@@ -36,6 +37,10 @@ func (wrapper *DeviceSetWrapper) DeactivateDevice(hash string) error {
 	return wrapper.wrapped.DeactivateDevice(wrapper.wrap(hash))
 }
 
+func (wrapper *DeviceSetWrapper) Shutdown() error {
+	return nil
+}
+
 func (wrapper *DeviceSetWrapper) RemoveDevice(hash string) error {
 	return wrapper.wrapped.RemoveDevice(wrapper.wrap(hash))
 }

+ 50 - 4
devmapper/deviceset_devmapper.go

@@ -40,6 +40,7 @@ type DeviceSetDM struct {
 	TransactionId    uint64
 	NewTransactionId uint64
 	nextFreeDevice   int
+	activeMounts map[string]int
 }
 
 func getDevName(name string) string {
@@ -348,8 +349,8 @@ func (devices *DeviceSetDM) deleteDevice(deviceId int) error {
 	return nil
 }
 
-func (devices *DeviceSetDM) removeDevice(info *DevInfo) error {
-	task, err := devices.createTask(DeviceRemove, info.Name())
+func (devices *DeviceSetDM) removeDevice(name string) error {
+	task, err := devices.createTask(DeviceRemove, name)
 	if task == nil {
 		return err
 	}
@@ -763,7 +764,7 @@ func (devices *DeviceSetDM) RemoveDevice(hash string) error {
 
 	devinfo, _ := devices.getInfo(info.Name())
 	if devinfo != nil && devinfo.Exists != 0 {
-		err := devices.removeDevice(info)
+		err := devices.removeDevice(info.Name())
 		if err != nil {
 			return err
 		}
@@ -809,7 +810,7 @@ func (devices *DeviceSetDM) DeactivateDevice(hash string) error {
 		return err
 	}
 	if devinfo.Exists != 0 {
-		err := devices.removeDevice(info)
+		err := devices.removeDevice(info.Name())
 		if err != nil {
 			return err
 		}
@@ -818,6 +819,39 @@ func (devices *DeviceSetDM) DeactivateDevice(hash string) error {
 	return nil
 }
 
+func (devices *DeviceSetDM) Shutdown() error {
+	if !devices.initialized {
+		return nil
+	}
+
+	for path, count := range devices.activeMounts {
+		for i := count; i > 0; i-- {
+			err := syscall.Unmount(path, 0)
+			if err != nil {
+				fmt.Printf("Shutdown unmounting %s, error: %s\n", path, err)
+			}
+		}
+		delete(devices.activeMounts, path)
+	}
+
+	for _, d := range devices.Devices {
+		if err := devices.DeactivateDevice(d.Hash); err != nil {
+			fmt.Printf("Shutdown deactivate %s , error: %s\n", d.Hash, err)
+		}
+	}
+
+
+	pool := devices.getPoolDevName()
+	devinfo, err := devices.getInfo(pool)
+	if err == nil && devinfo.Exists != 0 {
+		if err := devices.removeDevice(pool); err != nil {
+			fmt.Printf("Shutdown deactivate %s , error: %s\n", pool, err)
+		}
+	}
+
+	return nil
+}
+
 func (devices *DeviceSetDM) MountDevice(hash, path string) error {
 	if err := devices.ensureInit(); err != nil {
 		return err
@@ -837,6 +871,10 @@ func (devices *DeviceSetDM) MountDevice(hash, path string) error {
 	if err != nil {
 		return err
 	}
+
+	count := devices.activeMounts[path]
+	devices.activeMounts[path] = count + 1
+
 	return nil
 }
 
@@ -846,6 +884,13 @@ func (devices *DeviceSetDM) UnmountDevice(hash, path string) error {
 		return err
 	}
 
+	count := devices.activeMounts[path]
+	if count > 1 {
+		devices.activeMounts[path] = count - 1
+	} else {
+		delete(devices.activeMounts, path)
+	}
+
 	return nil
 }
 
@@ -913,6 +958,7 @@ func NewDeviceSetDM(root string) *DeviceSetDM {
 		devicePrefix: base,
 	}
 	devices.Devices = make(map[string]*DevInfo)
+	devices.activeMounts = make(map[string]int)
 
 	return devices
 }

+ 7 - 0
runtime_test.go

@@ -64,6 +64,13 @@ func cleanup(runtime *Runtime) error {
 	return nil
 }
 
+func cleanupLast(runtime *Runtime) error {
+	cleanup(runtime)
+	runtime.deviceSet.Shutdown()
+	return nil
+}
+
+
 func layerArchive(tarfile string) (io.Reader, error) {
 	// FIXME: need to close f somewhere
 	f, err := os.Open(tarfile)

+ 1 - 1
z_final_test.go

@@ -11,7 +11,7 @@ func displayFdGoroutines(t *testing.T) {
 }
 
 func TestFinal(t *testing.T) {
-	cleanup(globalRuntime)
+	cleanupLast(globalRuntime)
 	t.Logf("Start Fds: %d, Start Goroutines: %d", startFds, startGoroutines)
 	displayFdGoroutines(t)
 }