mirror of https://github.com/apache/cloudstack.git
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:
parent
63491fb893
commit
da2f5b83c5
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue