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]>'].