CS-15430 Create snapshot should fail if creating snapshot results in exceeding snapshot resource limit for domain-admin or user accounts

Reviewed-by: devdeep.singh@citrix.com
Change:
1. Before creating the snapshot, we synchronized checkresourcelimit to allow the users to create the snapshot and increment the resource count.
2. Depending on the failure of snapshot creation/ backup, we are decrementing the resource count.
This commit is contained in:
Deepti Dohare 2012-07-06 15:05:18 +05:30
parent 63491fb893
commit da2f5b83c5
1 changed files with 46 additions and 25 deletions

View File

@ -370,24 +370,32 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
@DB
@ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "creating snapshot", async = true)
public SnapshotVO createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner) {
VolumeVO volume = _volsDao.findById(volumeId);
VolumeVO volume = _volsDao.findById(volumeId);
if (volume == null) {
throw new InvalidParameterValueException("No such volume exist");
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
throw new InvalidParameterValueException("No such volume exist");
}
if (volume.getState() != Volume.State.Ready) {
throw new InvalidParameterValueException("Volume is not in ready state");
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
throw new InvalidParameterValueException("Volume is not in ready state");
}
SnapshotVO snapshot = null;
boolean backedUp = false;
UserVmVO uservm = null;
// does the caller have the authority to act on this volume
_accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume);
try {
_accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume);
} catch ( PermissionDeniedException pe) {
// decrement the resource count
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
s_logger.debug("Decrementing the resource count for account: " + snapshotOwner.getAccountName() + ", access failed");
throw pe;
}
try {
Long poolId = volume.getPoolId();
if (poolId == null) {
throw new CloudRuntimeException("You cannot take a snapshot of a volume until it has been attached to an instance");
@ -442,7 +450,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volumeId + " is being used, try it later ");
}
}*/
snapshot = createSnapshotOnPrimary(volume, policyId, snapshotId);
if (snapshot != null) {
if (snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) {
@ -475,18 +482,23 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
_usageEventDao.persist(usageEvent);
}
if( !backedUp ) {
snapshot.setStatus(Status.Error);
_snapshotDao.update(snapshot.getId(), snapshot);
//Decrement Resource Count
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
s_logger.debug("Decrementing the snapshot resource count for account: " + snapshotOwner.getAccountName() + " as backup failed");
} else {
_resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
s_logger.debug("Backup of the snapshot for account id :" + snapshotOwner.getAccountName() + ", successfully completed");
}
} else {
snapshot = _snapshotDao.findById(snapshotId);
if (snapshot != null) {
snapshot.setStatus(Status.Error);
_snapshotDao.update(snapshotId, snapshot);
}
//Decrement Resource Count
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
s_logger.debug("Decrementing the snapshot resource count for account: " + snapshotOwner.getAccountName() + " as snapshot creation failed");
snapshot = _snapshotDao.findById(snapshotId);
if(snapshot != null) {
snapshot.setStatus(Status.Error);
_snapshotDao.update(snapshotId, snapshot);
}
}
/*
@ -497,7 +509,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
}*/
}
return snapshot;
}
@ -1312,15 +1323,21 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
Type snapshotType = getSnapshotType(policyId);
Account owner = _accountMgr.getAccount(volume.getAccountId());
try{
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
//synchronize the resource count
synchronized (this) {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
//Increment the resourceCount
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.snapshot);
s_logger.debug("Incrementing the snapshot resource count for account : " + owner.getAccountName());
}
} catch (ResourceAllocationException e){
if (snapshotType != Type.MANUAL){
String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
s_logger.warn(msg);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg,
"Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
}
throw e;
if (snapshotType != Type.MANUAL){
String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
s_logger.warn(msg);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg,
"Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
}
throw e;
}
// Determine the name for this snapshot
@ -1335,14 +1352,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
String snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString;
// Create the Snapshot object and save it so we can return it to the
// user
// user
HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId);
SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), null, snapshotName,
(short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType);
SnapshotVO snapshot = _snapshotDao.persist(snapshotVO);
if (snapshot == null) {
//Decrement the resource count
_resourceLimitMgr.decrementResourceCount(owner.getId(), ResourceType.snapshot);
s_logger.debug("Decrementing the snapshot resource count for account: " + owner.getAccountName() + " as snapshot creation failed for volume");
throw new CloudRuntimeException("Failed to create snapshot for volume: "+volumeId);
}
return snapshot;
}