diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index b97a7d77ca1..edcfa67e391 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -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; }