]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Fallback to use lvchange first if lvremove fails
authorChang Liu <lingjiao.lc@taobao.com>
Tue, 22 Nov 2011 07:24:25 +0000 (15:24 +0800)
committerOsier Yang <jyang@redhat.com>
Tue, 22 Nov 2011 07:24:25 +0000 (15:24 +0800)
virStorageBackendLogicalDeleteVol() could not remove the lv with error
"could not remove open logical volume" sometimes. Generally it's caused
by the volume is still active, even if lvremove tries to remove it with
option "--force".

This patch is to fix it by disbale the lv first using "lvchange -aln"
and "lvremove -f" afterwards if the direct "lvremove -f" failed.

configure.ac
src/storage/storage_backend_logical.c

index 58c27406da72d86905687e508c0675c416eeff0a..e03e401448a9926576299c963f0271c17e979cbb 100644 (file)
@@ -1715,6 +1715,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
   AC_PATH_PROG([PVREMOVE], [pvremove], [], [$PATH:/sbin:/usr/sbin])
   AC_PATH_PROG([VGREMOVE], [vgremove], [], [$PATH:/sbin:/usr/sbin])
   AC_PATH_PROG([LVREMOVE], [lvremove], [], [$PATH:/sbin:/usr/sbin])
+  AC_PATH_PROG([LVCHANGE], [lvchange], [], [$PATH:/sbin:/usr/sbin])
   AC_PATH_PROG([VGCHANGE], [vgchange], [], [$PATH:/sbin:/usr/sbin])
   AC_PATH_PROG([VGSCAN], [vgscan], [], [$PATH:/sbin:/usr/sbin])
   AC_PATH_PROG([PVS], [pvs], [], [$PATH:/sbin:/usr/sbin])
@@ -1728,6 +1729,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
     if test -z "$PVREMOVE" ; then AC_MSG_ERROR([We need pvremove for LVM storage driver]) ; fi
     if test -z "$VGREMOVE" ; then AC_MSG_ERROR([We need vgremove for LVM storage driver]) ; fi
     if test -z "$LVREMOVE" ; then AC_MSG_ERROR([We need lvremove for LVM storage driver]) ; fi
+    if test -z "$LVCHANGE" ; then AC_MSG_ERROR([We need lvchange for LVM storage driver]) ; fi
     if test -z "$VGCHANGE" ; then AC_MSG_ERROR([We need vgchange for LVM storage driver]) ; fi
     if test -z "$VGSCAN" ; then AC_MSG_ERROR([We need vgscan for LVM storage driver]) ; fi
     if test -z "$PVS" ; then AC_MSG_ERROR([We need pvs for LVM storage driver]) ; fi
@@ -1740,6 +1742,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
     if test -z "$PVREMOVE" ; then with_storage_lvm=no ; fi
     if test -z "$VGREMOVE" ; then with_storage_lvm=no ; fi
     if test -z "$LVREMOVE" ; then with_storage_lvm=no ; fi
+    if test -z "$LVCHANGE" ; then with_storage_lvm=no ; fi
     if test -z "$VGCHANGE" ; then with_storage_lvm=no ; fi
     if test -z "$VGSCAN" ; then with_storage_lvm=no ; fi
     if test -z "$PVS" ; then with_storage_lvm=no ; fi
@@ -1757,6 +1760,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
     AC_DEFINE_UNQUOTED([PVREMOVE],["$PVREMOVE"],[Location of pvremove program])
     AC_DEFINE_UNQUOTED([VGREMOVE],["$VGREMOVE"],[Location of vgremove program])
     AC_DEFINE_UNQUOTED([LVREMOVE],["$LVREMOVE"],[Location of lvremove program])
+    AC_DEFINE_UNQUOTED([LVCHANGE],["$LVCHANGE"],[Location of lvchange program])
     AC_DEFINE_UNQUOTED([VGCHANGE],["$VGCHANGE"],[Location of vgchange program])
     AC_DEFINE_UNQUOTED([VGSCAN],["$VGSCAN"],[Location of vgscan program])
     AC_DEFINE_UNQUOTED([PVS],["$PVS"],[Location of pvs program])
index 8118d0898f9df713a180b6b6b9ebd146f605b4c0..61c89a2b851c398fd8fa17c5c76102555c5210b9 100644 (file)
@@ -775,20 +775,40 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
                                   virStorageVolDefPtr vol,
                                   unsigned int flags)
 {
-    const char *cmdargv[] = {
-        LVREMOVE, "-f", vol->target.path, NULL
-    };
+    int ret = -1;
+
+    virCommandPtr lvchange_cmd = NULL;
+    virCommandPtr lvremove_cmd = NULL;
 
     virCheckFlags(0, -1);
 
     virFileWaitForDevices();
 
-    if (virRun(cmdargv, NULL) < 0)
-        return -1;
+    lvchange_cmd = virCommandNewArgList(LVCHANGE,
+                                        "-aln",
+                                        vol->target.path,
+                                        NULL);
 
-    return 0;
-}
+    lvremove_cmd = virCommandNewArgList(LVREMOVE,
+                                        "-f",
+                                        vol->target.path,
+                                        NULL);
 
+    if (virCommandRun(lvremove_cmd, NULL) < 0) {
+        if (virCommandRun(lvchange_cmd, NULL) < 0) {
+            goto cleanup;
+        } else {
+            if (virCommandRun(lvremove_cmd, NULL) < 0)
+                goto cleanup;
+        }
+    }
+
+    ret = 0;
+cleanup:
+    virCommandFree(lvchange_cmd);
+    virCommandFree(lvremove_cmd);
+    return ret;
+}
 
 virStorageBackend virStorageBackendLogical = {
     .type = VIR_STORAGE_POOL_LOGICAL,