Browse Source

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 years ago
parent
commit
c6e8813c97
4 changed files with 63 additions and 5 deletions
  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)
 }