cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From weiz...@apache.org
Subject git commit: updated refs/heads/4.1 to 1978d7b
Date Wed, 07 Aug 2013 07:57:15 GMT
Updated Branches:
  refs/heads/4.1 55d13c97c -> 1978d7bd7


CLOUDSTACK-2729: use file lock to prevent concurrent refreshPool/deleteVolume on KVM shared
storage pool

Signed-off-by: Edison Su <sudison@gmail.com>
(cherry picked from commit 1e4ff7f4532a39355ef5e5bfaa8dbfbc1f1c27e4)


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1978d7bd
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1978d7bd
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1978d7bd

Branch: refs/heads/4.1
Commit: 1978d7bd7311d19a4b370a679cfd364d54e1e300
Parents: 55d13c9
Author: Wei Zhou <w.zhou@leaseweb.com>
Authored: Mon Aug 5 11:21:00 2013 -0700
Committer: Wei Zhou <w.zhou@leaseweb.com>
Committed: Wed Aug 7 09:56:30 2013 +0200

----------------------------------------------------------------------
 .../kvm/storage/LibvirtStorageAdaptor.java      | 79 ++++++++++++++++++--
 1 file changed, 74 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1978d7bd/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index 9f85132..3f0e6e5 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -17,6 +17,7 @@
 package com.cloud.hypervisor.kvm.storage;
 
 import java.io.File;
+import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -57,6 +58,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
     private StorageLayer _storageLayer;
     private String _mountPoint = "/mnt";
     private String _manageSnapshotPath;
+    private String _lockfile = "KVMFILELOCK" + File.separator + ".lock";
 
     public LibvirtStorageAdaptor(StorageLayer storage) {
         _storageLayer = storage;
@@ -104,7 +106,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
     public void storagePoolRefresh(StoragePool pool) {
         try {
             synchronized (getStoragePool(pool.getUUIDString())) {
-                pool.refresh(0);
+                refreshPool(pool);
             }
         } catch (LibvirtException e) {
 
@@ -389,8 +391,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
             }
             LibvirtStoragePoolDef spd = getStoragePoolDef(conn, storage);
             StoragePoolType type = null;
-            if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.NETFS
-                    || spd.getPoolType() == LibvirtStoragePoolDef.poolType.DIR) {
+            if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.NETFS) {
+                type = StoragePoolType.NetworkFilesystem;
+            } else if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.DIR) {
                 type = StoragePoolType.Filesystem;
             } else if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.RBD) {
                 type = StoragePoolType.RBD;
@@ -666,7 +669,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
         LibvirtStoragePool libvirtPool = (LibvirtStoragePool) pool;
         try {
             StorageVol vol = this.getVolume(libvirtPool.getPool(), uuid);
-            vol.delete(0);
+            deleteVol(libvirtPool, vol);
             vol.free();
             return true;
         } catch (LibvirtException e) {
@@ -840,7 +843,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
         LibvirtStoragePool libvirtPool = (LibvirtStoragePool) pool;
         StoragePool virtPool = libvirtPool.getPool();
         try {
-            virtPool.refresh(0);
+            refreshPool(virtPool);
         } catch (LibvirtException e) {
             return false;
         }
@@ -868,4 +871,70 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
         return true;
     }
 
+    // refreshPool and deleteVol are used to fix CLOUDSTACK-2729/CLOUDSTACK-2780
+    // They are caused by a libvirt bug (https://bugzilla.redhat.com/show_bug.cgi?id=977706)
+    // However, we also need to fix the issues in CloudStack source code.
+    // A file lock is used to prevent deleting a volume from a KVM storage pool when refresh
it.
+    private void refreshPool(StoragePool pool) throws LibvirtException {
+        Connect conn = LibvirtConnection.getConnection();
+        LibvirtStoragePoolDef spd = getStoragePoolDef(conn, pool);
+        if ((! spd.getPoolType().equals(LibvirtStoragePoolDef.poolType.NETFS))
+                && (! spd.getPoolType().equals(LibvirtStoragePoolDef.poolType.DIR)))
{
+            pool.refresh(0);
+            return;
+        }
+        String lockFile = _mountPoint + File.separator + pool.getUUIDString() + File.separator
+ _lockfile;
+        if (lock(lockFile, 30)) {
+            try {
+                pool.refresh(0);
+            } finally {
+                unlock(lockFile);
+            }
+        } else {
+            throw new CloudRuntimeException("Can not get file lock to refresh the pool "
+ pool.getUUIDString());
+        }
+    }
+
+    private void deleteVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException
{
+        if ((! pool.getType().equals(StoragePoolType.NetworkFilesystem))
+                && (! pool.getType().equals(StoragePoolType.Filesystem))) {
+            vol.delete(0);
+            return;
+        }
+        String lockFile = pool.getLocalPath() + File.separator + _lockfile;
+        if (lock(lockFile, 30)) {
+            try {
+                vol.delete(0);
+            } finally {
+                unlock(lockFile);
+            }
+        } else {
+            throw new CloudRuntimeException("Can not get file lock to delete the volume "
+ vol.getPath());
+        }
+    }
+
+    private boolean lock(String path, int wait) {
+        File lockFile = new File(path);
+        lockFile.getParentFile().mkdir();
+        boolean havelock = false;
+        try {
+            while (wait > 0) {
+                if (lockFile.createNewFile()) {
+                    havelock = true;
+                    break;
+                }
+                s_logger.debug("lockFile " + _lockfile + " already exists, waiting 1000 ms");
+                Thread.sleep(1000);
+                wait--;
+            }
+        } catch (IOException e) {
+        } catch (InterruptedException e) {
+        }
+        return havelock;
+    }
+
+    private void unlock(String path) {
+        File lockFile = new File(path);
+        lockFile.delete();
+    }
 }


Mime
View raw message