cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edi...@apache.org
Subject git commit: updated refs/heads/4.2 to 0f539b4
Date Mon, 05 Aug 2013 18:21:48 GMT
Updated Branches:
  refs/heads/4.2 001ff45a7 -> 0f539b4ce


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

Signed-off-by: Edison Su <sudison@gmail.com>


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

Branch: refs/heads/4.2
Commit: 0f539b4ce1b07c672a776ffa806dabb70c528afe
Parents: 001ff45
Author: Wei Zhou <w.zhou@leaseweb.com>
Authored: Mon Aug 5 11:21:00 2013 -0700
Committer: Edison Su <sudison@gmail.com>
Committed: Mon Aug 5 11:21:00 2013 -0700

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


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0f539b4c/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 e779162..22a1be9 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
@@ -72,6 +72,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
     private StorageLayer _storageLayer;
     private String _mountPoint = "/mnt";
     private String _manageSnapshotPath;
+    private String _lockfile = "KVMFILELOCK" + File.separator + ".lock";
 
     private String rbdTemplateSnapName = "cloudstack-base-snap";
     private int rbdFeatures = (1<<0); /* Feature 1<<0 means layering in RBD format
2 */
@@ -123,7 +124,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
     public void storagePoolRefresh(StoragePool pool) {
         try {
             synchronized (getStoragePool(pool.getUUIDString())) {
-                pool.refresh(0);
+                refreshPool(pool);
             }
         } catch (LibvirtException e) {
 
@@ -359,8 +360,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;
@@ -731,7 +733,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) {
@@ -1131,7 +1133,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;
         }
@@ -1159,4 +1161,64 @@ 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)) {
+            pool.refresh(0);
+            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)) {
+            vol.delete(0);
+            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