|
@@ -42,7 +42,7 @@ func ListAllLoopDevices() ([]*LoopDevice, error) {
|
|
imageName := strings.TrimPrefix(strings.TrimSpace(fields[2]), "(")
|
|
imageName := strings.TrimPrefix(strings.TrimSpace(fields[2]), "(")
|
|
imageName = strings.TrimSuffix(imageName, ")")
|
|
imageName = strings.TrimSuffix(imageName, ")")
|
|
devices = append(devices, &LoopDevice{
|
|
devices = append(devices, &LoopDevice{
|
|
- Device: fields[0],
|
|
|
|
|
|
+ Device: strings.TrimSuffix(fields[0], ":"),
|
|
PartitionRange: fields[1],
|
|
PartitionRange: fields[1],
|
|
ImageFile: imageName,
|
|
ImageFile: imageName,
|
|
})
|
|
})
|
|
@@ -67,6 +67,42 @@ func MountImageAsLoopDevice(imagePath string) error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Unmount a loop device by the image path
|
|
|
|
+func UnmountLoopDeviceByImagePath(imagePath string) error {
|
|
|
|
+ imagePathIsMounted, err := ImageMountedAsLoopDevice(imagePath)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if !imagePathIsMounted {
|
|
|
|
+ //Image already unmounted. No need to unmount
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ loopDriveID, err := GetLoopDriveIDFromImagePath(imagePath)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //As we checked for mounted above, no need to check if loopDriveID is empty string
|
|
|
|
+ return UnmountLoopDeviceByID(loopDriveID)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Unmount the loop device by id e.g. /dev/loop1
|
|
|
|
+func UnmountLoopDeviceByID(loopDevId string) error {
|
|
|
|
+ cmd := exec.Command("sudo", "losetup", "-d", loopDevId)
|
|
|
|
+
|
|
|
|
+ cmd.Stdout = os.Stdout
|
|
|
|
+ cmd.Stderr = os.Stderr
|
|
|
|
+
|
|
|
|
+ err := cmd.Run()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return fmt.Errorf("delete loopback device failed: %v", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
// Get loopdrive ID (/dev/loop1) by the image path, return empty string if not found error if load failed
|
|
// Get loopdrive ID (/dev/loop1) by the image path, return empty string if not found error if load failed
|
|
func GetLoopDriveIDFromImagePath(imagePath string) (string, error) {
|
|
func GetLoopDriveIDFromImagePath(imagePath string) (string, error) {
|
|
absPath, err := filepath.Abs(imagePath)
|
|
absPath, err := filepath.Abs(imagePath)
|
|
@@ -90,7 +126,7 @@ func GetLoopDriveIDFromImagePath(imagePath string) (string, error) {
|
|
}
|
|
}
|
|
|
|
|
|
// Check if an image file is already mounted as loop drive
|
|
// Check if an image file is already mounted as loop drive
|
|
-func ImageAlreadyMounted(imagePath string) (bool, error) {
|
|
|
|
|
|
+func ImageMountedAsLoopDevice(imagePath string) (bool, error) {
|
|
loopDriveId, err := GetLoopDriveIDFromImagePath(imagePath)
|
|
loopDriveId, err := GetLoopDriveIDFromImagePath(imagePath)
|
|
if err != nil {
|
|
if err != nil {
|
|
return false, err
|
|
return false, err
|