This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 36f43b5  CLOUDSTACK-10202: createSnapshotPolicy API create multiple 
entries in DB for same volume. (#2373)
36f43b5 is described below

commit 36f43b5d53e7720d10217ada2c5b926a833dd6bb
Author: niteshsarda <[email protected]>
AuthorDate: Tue Jan 2 08:53:46 2018 +0530

    CLOUDSTACK-10202: createSnapshotPolicy API create multiple entries in DB 
for same volume. (#2373)
    
    createSnapshotPolicy API create multiple entries in DB for same parameters, 
if multiple threads are executed in parallel.
    
    STEPS TO REPRODUCE :
    
    Created a new machine having root and data disk.
    Make sure that no existing snapshot policy is present for the volume.
    Execute multiple threads in parallel for createSnapshotPolicy API having 
all required parameters exactly same.
    Verify table snapshot_policy in DB, will get multiple entries for same 
policy.
    Once again execute same multiple threads, by changing any API parameter, 
will see that existing entries are getting modified in DB and no new entries 
are added.
---
 .../storage/snapshot/SnapshotManagerImpl.java      | 52 +++++++++++++---------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java 
b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index f074c33..2c4de7e 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -17,6 +17,7 @@
 package com.cloud.storage.snapshot;
 
 import com.cloud.agent.api.Answer;
+import com.cloud.utils.db.GlobalLock;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.DeleteSnapshotsDirCommand;
 import com.cloud.alert.AlertManager;
@@ -785,6 +786,7 @@ public class SnapshotManagerImpl extends 
MutualExclusiveIdsManagerBase implement
     public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account 
policyOwner) {
         Long volumeId = cmd.getVolumeId();
         boolean display = cmd.isDisplay();
+        SnapshotPolicyVO policy = null;
         VolumeVO volume = _volsDao.findById(cmd.getVolumeId());
         if (volume == null) {
             throw new InvalidParameterValueException("Failed to create 
snapshot policy, unable to find a volume with id " + volumeId);
@@ -854,33 +856,39 @@ public class SnapshotManagerImpl extends 
MutualExclusiveIdsManagerBase implement
                 throw new InvalidParameterValueException("Max number of 
snapshots shouldn't exceed the " + message + " level snapshot limit");
             }
         }
-        SnapshotPolicyVO policy = 
_snapshotPolicyDao.findOneByVolumeInterval(volumeId, intvType);
-        if (policy == null) {
-            policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), 
timezoneId, intvType, cmd.getMaxSnaps(), display);
-            policy = _snapshotPolicyDao.persist(policy);
-            _snapSchedMgr.scheduleNextSnapshotJob(policy);
-        } else {
+
+        final GlobalLock createSnapshotPolicyLock = 
GlobalLock.getInternLock("createSnapshotPolicy_" + volumeId);
+        boolean isLockAcquired = createSnapshotPolicyLock.lock(5);
+        if (isLockAcquired) {
+            s_logger.debug("Acquired lock for creating snapshot policy of 
volume : " + volume.getName());
             try {
-                boolean previousDisplay = policy.isDisplay();
-                policy = _snapshotPolicyDao.acquireInLockTable(policy.getId());
-                policy.setSchedule(cmd.getSchedule());
-                policy.setTimezone(timezoneId);
-                policy.setInterval((short)intvType.ordinal());
-                policy.setMaxSnaps(cmd.getMaxSnaps());
-                policy.setActive(true);
-                policy.setDisplay(display);
-                _snapshotPolicyDao.update(policy.getId(), policy);
-                
_snapSchedMgr.scheduleOrCancelNextSnapshotJobOnDisplayChange(policy, 
previousDisplay);
-            } finally {
-                if (policy != null) {
-                    _snapshotPolicyDao.releaseFromLockTable(policy.getId());
+                policy = _snapshotPolicyDao.findOneByVolumeInterval(volumeId, 
intvType);
+                if (policy == null) {
+                    policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), 
timezoneId, intvType, cmd.getMaxSnaps(), display);
+                    policy = _snapshotPolicyDao.persist(policy);
+                    _snapSchedMgr.scheduleNextSnapshotJob(policy);
+                } else {
+                    boolean previousDisplay = policy.isDisplay();
+                    policy.setSchedule(cmd.getSchedule());
+                    policy.setTimezone(timezoneId);
+                    policy.setInterval((short)intvType.ordinal());
+                    policy.setMaxSnaps(cmd.getMaxSnaps());
+                    policy.setActive(true);
+                    policy.setDisplay(display);
+                    _snapshotPolicyDao.update(policy.getId(), policy);
+                    
_snapSchedMgr.scheduleOrCancelNextSnapshotJobOnDisplayChange(policy, 
previousDisplay);
                 }
+            } finally {
+                createSnapshotPolicyLock.unlock();
             }
 
+            // TODO - Make createSnapshotPolicy - BaseAsyncCreate and remove 
this.
+            CallContext.current().putContextParameter(SnapshotPolicy.class, 
policy.getUuid());
+            return policy;
+        } else {
+            s_logger.warn("Unable to acquire lock for creating snapshot policy 
of volume : " + volume.getName());
+            return null;
         }
-        // TODO - Make createSnapshotPolicy - BaseAsyncCreate and remove this.
-        CallContext.current().putContextParameter(SnapshotPolicy.class, 
policy.getUuid());
-        return policy;
     }
 
     protected boolean deletePolicy(long userId, Long policyId) {

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to