Reorganized the snapshot logic a bit
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c7aa9b44 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c7aa9b44 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c7aa9b44 Branch: refs/heads/hotfix/CLOUDSTACK-7776 Commit: c7aa9b44390781a5efab425f4212efb4d9758f82 Parents: 3690574 Author: Mike Tutkowski <mike.tutkow...@solidfire.com> Authored: Tue Oct 21 12:22:05 2014 -0600 Committer: Mike Tutkowski <mike.tutkow...@solidfire.com> Committed: Tue Oct 21 16:01:15 2014 -0600 ---------------------------------------------------------------------- .../snapshot/StorageSystemSnapshotStrategy.java | 177 ++++++++++--------- 1 file changed, 89 insertions(+), 88 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7aa9b44/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java ---------------------------------------------------------------------- diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java index a0d685f..41019fb 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java @@ -164,127 +164,128 @@ public class StorageSystemSnapshotStrategy extends SnapshotStrategyBase { throw new CloudRuntimeException("Failed to acquire lock on the following snapshot: " + snapshotInfo.getId()); } + SnapshotResult result = null; + try { volumeInfo.stateTransit(Volume.Event.SnapshotRequested); - SnapshotResult result = null; + // tell the storage driver to create a back-end volume (eventually used to create a new SR on and to copy the VM snapshot VDI to) + result = snapshotSvr.takeSnapshot(snapshotInfo); - try { - // tell the storage driver to create a back-end volume (eventually used to create a new SR on and to copy the VM snapshot VDI to) - result = snapshotSvr.takeSnapshot(snapshotInfo); + if (result.isFailed()) { + s_logger.debug("Failed to take a snapshot: " + result.getResult()); - if (result.isFailed()) { - s_logger.debug("Failed to take a snapshot: " + result.getResult()); + throw new CloudRuntimeException(result.getResult()); + } - throw new CloudRuntimeException(result.getResult()); - } + // send a command to XenServer to create a VM snapshot on the applicable SR (get back the VDI UUID of the VM snapshot) - // send a command to XenServer to create a VM snapshot on the applicable SR (get back the VDI UUID of the VM snapshot) + performSnapshotAndCopyOnHostSide(volumeInfo, snapshotInfo); - Map<String, String> sourceDetails = null; + markAsBackedUp((SnapshotObject)result.getSnashot()); + } + finally { + if (result != null && result.isSuccess()) { + volumeInfo.stateTransit(Volume.Event.OperationSucceeded); + } + else { + volumeInfo.stateTransit(Volume.Event.OperationFailed); + } - VolumeVO volumeVO = _volumeDao.findById(volumeInfo.getId()); + if (snapshotVO != null) { + _snapshotDao.releaseFromLockTable(snapshotInfo.getId()); + } + } - Long vmInstanceId = volumeVO.getInstanceId(); - VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(vmInstanceId); + return snapshotInfo; + } - Long hostId = null; + private void performSnapshotAndCopyOnHostSide(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo) { + Map<String, String> sourceDetails = null; - // if the volume to snapshot is associated with a VM - if (vmInstanceVO != null) { - hostId = vmInstanceVO.getHostId(); + VolumeVO volumeVO = _volumeDao.findById(volumeInfo.getId()); - // if the VM is not associated with a host - if (hostId == null) { - sourceDetails = getSourceDetails(volumeInfo); + Long vmInstanceId = volumeVO.getInstanceId(); + VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(vmInstanceId); - hostId = vmInstanceVO.getLastHostId(); - } - } - // volume to snapshot is not associated with a VM (could be a data disk in the detached state) - else { - sourceDetails = getSourceDetails(volumeInfo); - } + Long hostId = null; - HostVO hostVO = getHostId(hostId, volumeVO); + // if the volume to snapshot is associated with a VM + if (vmInstanceVO != null) { + hostId = vmInstanceVO.getHostId(); - long storagePoolId = volumeVO.getPoolId(); - StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId); - DataStore dataStore = _dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary); + // if the VM is not associated with a host + if (hostId == null) { + sourceDetails = getSourceDetails(volumeInfo); - Map<String, String> destDetails = getDestDetails(storagePoolVO, snapshotInfo); + hostId = vmInstanceVO.getLastHostId(); + } + } + // volume to snapshot is not associated with a VM (could be a data disk in the detached state) + else { + sourceDetails = getSourceDetails(volumeInfo); + } - SnapshotAndCopyCommand snapshotAndCopyCommand = new SnapshotAndCopyCommand(volumeInfo.getPath(), sourceDetails, destDetails); + HostVO hostVO = getHostId(hostId, volumeVO); - SnapshotAndCopyAnswer snapshotAndCopyAnswer = null; + long storagePoolId = volumeVO.getPoolId(); + StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId); + DataStore dataStore = _dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary); - try { - // if sourceDetails != null, we need to connect the host(s) to the volume - if (sourceDetails != null) { - _volService.grantAccess(volumeInfo, hostVO, dataStore); - } + Map<String, String> destDetails = getDestDetails(storagePoolVO, snapshotInfo); - _volService.grantAccess(snapshotInfo, hostVO, dataStore); + SnapshotAndCopyCommand snapshotAndCopyCommand = new SnapshotAndCopyCommand(volumeInfo.getPath(), sourceDetails, destDetails); - snapshotAndCopyAnswer = (SnapshotAndCopyAnswer)_agentMgr.send(hostVO.getId(), snapshotAndCopyCommand); - } - catch (Exception e) { - throw new CloudRuntimeException(e.getMessage()); - } - finally { - try { - _volService.revokeAccess(snapshotInfo, hostVO, dataStore); + SnapshotAndCopyAnswer snapshotAndCopyAnswer = null; - // if sourceDetails != null, we need to disconnect the host(s) from the volume - if (sourceDetails != null) { - _volService.revokeAccess(volumeInfo, hostVO, dataStore); - } - } - catch (Exception ex) { - s_logger.debug(ex.getMessage(), ex); - } - } + try { + // if sourceDetails != null, we need to connect the host(s) to the volume + if (sourceDetails != null) { + _volService.grantAccess(volumeInfo, hostVO, dataStore); + } - if (snapshotAndCopyAnswer == null || !snapshotAndCopyAnswer.getResult()) { - final String errMsg; + _volService.grantAccess(snapshotInfo, hostVO, dataStore); - if (snapshotAndCopyAnswer != null && snapshotAndCopyAnswer.getDetails() != null && !snapshotAndCopyAnswer.getDetails().isEmpty()) { - errMsg = snapshotAndCopyAnswer.getDetails(); - } - else { - errMsg = "Unable to perform host-side operation"; - } + snapshotAndCopyAnswer = (SnapshotAndCopyAnswer)_agentMgr.send(hostVO.getId(), snapshotAndCopyCommand); + } + catch (Exception ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + finally { + try { + _volService.revokeAccess(snapshotInfo, hostVO, dataStore); - throw new CloudRuntimeException(errMsg); + // if sourceDetails != null, we need to disconnect the host(s) from the volume + if (sourceDetails != null) { + _volService.revokeAccess(volumeInfo, hostVO, dataStore); } - - String path = snapshotAndCopyAnswer.getPath(); // for XenServer, this is the VDI's UUID - - SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO(snapshotInfo.getId(), - DiskTO.PATH, - path, - false); - - _snapshotDetailsDao.persist(snapshotDetail); - - markAsBackedUp((SnapshotObject)result.getSnashot()); } - finally { - if (result != null && result.isSuccess()) { - volumeInfo.stateTransit(Volume.Event.OperationSucceeded); - } - else { - volumeInfo.stateTransit(Volume.Event.OperationFailed); - } + catch (Exception ex) { + s_logger.debug(ex.getMessage(), ex); } } - finally { - if (snapshotVO != null) { - _snapshotDao.releaseFromLockTable(snapshotInfo.getId()); + + if (snapshotAndCopyAnswer == null || !snapshotAndCopyAnswer.getResult()) { + final String errMsg; + + if (snapshotAndCopyAnswer != null && snapshotAndCopyAnswer.getDetails() != null && !snapshotAndCopyAnswer.getDetails().isEmpty()) { + errMsg = snapshotAndCopyAnswer.getDetails(); + } + else { + errMsg = "Unable to perform host-side operation"; } + + throw new CloudRuntimeException(errMsg); } - return snapshotInfo; + String path = snapshotAndCopyAnswer.getPath(); // for XenServer, this is the VDI's UUID + + SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO(snapshotInfo.getId(), + DiskTO.PATH, + path, + false); + + _snapshotDetailsDao.persist(snapshotDetail); } private Map<String, String> getSourceDetails(VolumeInfo volumeInfo) {