public SnapshotObjectTO(SnapshotInfo snapshot) { this.path = snapshot.getPath(); this.setId(snapshot.getId()); VolumeInfo vol = snapshot.getBaseVolume(); if (vol != null) { this.volume = (VolumeObjectTO)vol.getTO(); this.setVmName(vol.getAttachedVmName()); } SnapshotInfo parentSnapshot = snapshot.getParent(); ArrayList<String> parentsArry = new ArrayList<String>(); if (parentSnapshot != null) { this.parentSnapshotPath = parentSnapshot.getPath(); while(parentSnapshot != null) { parentsArry.add(parentSnapshot.getPath()); parentSnapshot = parentSnapshot.getParent(); } parents = parentsArry.toArray(new String[parentsArry.size()]); ArrayUtils.reverse(parents); } this.dataStore = snapshot.getDataStore().getTO(); this.setName(snapshot.getName()); this.hypervisorType = snapshot.getHypervisorType(); this.quiescevm = false; }
@Override public SnapshotInfo backupSnapshot(SnapshotInfo snapshotInfo) { Preconditions.checkArgument(snapshotInfo != null, "'snapshotInfo' cannot be 'null'."); if (snapshotInfo.getLocationType() != Snapshot.LocationType.SECONDARY) { markAsBackedUp((SnapshotObject)snapshotInfo); return snapshotInfo; } // At this point, the snapshot is either taken as a native // snapshot on the storage or exists as a volume on the storage (clone). // If archive flag is passed in, we should copy this snapshot to secondary // storage and delete it from primary storage. HostVO host = getHost(snapshotInfo.getVolumeId()); boolean canStorageSystemCreateVolumeFromSnapshot = canStorageSystemCreateVolumeFromSnapshot(snapshotInfo.getBaseVolume().getPoolId()); if (!canStorageSystemCreateVolumeFromSnapshot) { String msg = "Cannot archive snapshot: 'canStorageSystemCreateVolumeFromSnapshot' was false."; s_logger.warn(msg); throw new CloudRuntimeException(msg); } boolean computeClusterSupportsResign = clusterDao.getSupportsResigning(host.getClusterId()); if (!computeClusterSupportsResign) { String msg = "Cannot archive snapshot: 'computeClusterSupportsResign' was false."; s_logger.warn(msg); throw new CloudRuntimeException(msg); } return snapshotSvr.backupSnapshot(snapshotInfo); }
@Override public void doInTransactionWithoutResult(TransactionStatus status) { _snapshotDetailsDao.removeDetail(((SnapshotObject)snapshotOnPrimary).getId(), AsyncJob.Constants.MS_ID); DataStore primaryStore = snapshotOnPrimary.getDataStore(); try { SnapshotInfo parent = snapshotOnPrimary.getParent(); if (parent != null && primaryStore instanceof PrimaryDataStoreImpl) { if (((PrimaryDataStoreImpl)primaryStore).getPoolType() != StoragePoolType.RBD) { Long parentSnapshotId = parent.getId(); while (parentSnapshotId != null && parentSnapshotId != 0L) { SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId); if (snapshotDataStoreVO != null) { parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId(); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_OFF_PRIMARY, parent.getAccountId(), parent.getDataCenterId(), parent.getId(), parent.getName(), null, null, 0L, 0L, parent.getClass().getName(), parent.getUuid()); snapshotStoreDao.remove(snapshotDataStoreVO.getId()); } else { SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), snapshotOnPrimary.getId()); if (snapshotDataStoreVO != null) { snapshotDataStoreVO.setParentSnapshotId(0L);
private Map<String, String> getSnapshotAttributes(SnapshotInfo snapshotInfo) { Map<String, String> mapAttributes = new HashMap<>(); mapAttributes.put(SolidFireUtil.CloudStackSnapshotId, String.valueOf(snapshotInfo.getId())); mapAttributes.put(SolidFireUtil.CloudStackSnapshotSize, NumberFormat.getInstance().format(snapshotInfo.getSize())); return mapAttributes; }
private void verifyLocationType(SnapshotInfo snapshotInfo) { VolumeInfo volumeInfo = snapshotInfo.getBaseVolume(); if (snapshotInfo.getLocationType() == Snapshot.LocationType.SECONDARY && volumeInfo.getFormat() != ImageFormat.VHD) { throw new CloudRuntimeException("Only the '" + ImageFormat.VHD + "' image type can be used when 'LocationType' is set to 'SECONDARY'."); } }
private void verifySnapshotType(SnapshotInfo snapshotInfo) { if (snapshotInfo.getHypervisorType() == HypervisorType.KVM && snapshotInfo.getDataStore().getRole() != DataStoreRole.Primary) { throw new CloudRuntimeException("For the KVM hypervisor type, you can only revert a volume to a snapshot state if the snapshot " + "resides on primary storage. For other snapshot types, create a volume from the snapshot to recover its data."); } }
snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot); } catch (Exception e) { s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage()); CreateSnapshotContext<CommandResult> context = new CreateSnapshotContext<CommandResult>(null, snap.getBaseVolume(), snapshotOnPrimary, future); AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createSnapshotAsyncCallback(null, null)).setContext(context); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_ON_PRIMARY, snap.getAccountId(), snap.getDataCenterId(), snap.getId(), snap.getName(), null, null, snapshotOnPrimary.getSize(), snapshotOnPrimary.getSize(), snap.getClass().getName(), snap.getUuid()); return result; } catch (InterruptedException e) {
protected boolean deleteSnapshotChain(SnapshotInfo snapshot) { s_logger.debug("delete snapshot chain for snapshot: " + snapshot.getId()); boolean result = false; boolean resultIsSet = false; //need to track, the snapshot itself is deleted or not. try { while (snapshot != null && (snapshot.getState() == Snapshot.State.Destroying || snapshot.getState() == Snapshot.State.Destroyed || snapshot.getState() == Snapshot.State.Error)) { SnapshotInfo child = snapshot.getChild(); break; s_logger.debug("Snapshot: " + snapshot.getId() + " doesn't have children, so it's ok to delete it and its parents"); SnapshotInfo parent = snapshot.getParent(); boolean deleted = false; if (parent != null) { if (parent.getPath() != null && parent.getPath().equalsIgnoreCase(snapshot.getPath())) { snapshot.processEvent(Event.DestroyRequested); snapshot.processEvent(Event.OperationSuccessed); deleted = true; if (!resultIsSet) { if (r) { List<SnapshotInfo> cacheSnaps = snapshotDataFactory.listSnapshotOnCache(snapshot.getId()); for (SnapshotInfo cacheSnap : cacheSnaps) { s_logger.debug("Delete snapshot " + snapshot.getId() + " from image cache store: " + cacheSnap.getDataStore().getName()); cacheSnap.delete();
@Override public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { SnapshotInfo parentSnapshot = snapshot.getParent(); if (parentSnapshot != null && snapshot.getPath().equalsIgnoreCase(parentSnapshot.getPath())) { SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); if (parentSnapshotOnBackupStore != null && parentSnapshotOnBackupStore.getState() == State.Ready) { DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), parentSnapshotOnBackupStore.getRole()); snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer); SnapshotObject snapObj = (SnapshotObject)snapshot; try { snapObj.processEvent(Snapshot.Event.OperationNotPerformed); } catch (NoTransitionException e) { s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString()); throw new CloudRuntimeException(e.toString()); SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Image); SnapshotDataStoreVO parentSnapshotOnPrimaryStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Primary); HypervisorType hypervisorType = snapshot.getBaseVolume().getHypervisorType(); if (parentSnapshotOnPrimaryStore != null && parentSnapshotOnBackupStore != null && hypervisorType == Hypervisor.HypervisorType.XenServer) { // CS does incremental backup only for XenServer SnapshotDataStoreVO oldestSnapshotOnPrimary = snapshotStoreDao.findOldestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Primary); VolumeVO volume = volumeDao.findById(snapshot.getVolumeId()); if (oldestSnapshotOnPrimary != null) { if (oldestSnapshotOnPrimary.getDataStoreId() == volume.getPoolId() && oldestSnapshotOnPrimary.getId() != parentSnapshotOnPrimaryStore.getId()) {
snapshotInfo.processEvent(Event.CopyingRequested); if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) { computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId()); else if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType()) || HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) { computeClusterSupportsVolumeClone = true; DataStore srcDataStore = snapshotInfo.getDataStore(); if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { keepGrantedAccess = HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()); if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { extraDetails = new HashMap<>(); String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK); if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN); CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value()); String msg = "Failed to create template from snapshot (Snapshot ID = " + snapshotInfo.getId() + ") : "; if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
postCreateSnapshot(volumeId, snapshot.getId(), policyId); SnapshotVO freshSnapshot = _snapshotDao.findById(snapshot.getId()); if (freshSnapshot != null) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
/** * If the underlying storage system needed to create a volume from a snapshot for createVolumeFromSnapshot(SnapshotInfo), then * this is its opportunity to delete that temporary volume and restore properties in snapshot_details to the way they were before the * invocation of createVolumeFromSnapshot(SnapshotInfo). */ private void deleteVolumeFromSnapshot(SnapshotInfo snapshotInfo) { SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "delete"); try { snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null); } finally { _snapshotDetailsDao.remove(snapshotDetails.getId()); } }
@Override public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshot2, AsyncCompletionCallback<CommandResult> callback) { VolumeInfo volumeInfo = snapshot.getBaseVolume(); VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId()); if (volumeVO == null || volumeVO.getRemoved() != null) { String errMsg = "The volume that the snapshot belongs to no longer exists."; CommandResult commandResult = new CommandResult(); commandResult.setResult(errMsg); callback.complete(commandResult); return; } SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(volumeVO.getPoolId(), storagePoolDetailsDao); long sfVolumeId = Long.parseLong(volumeInfo.getFolder()); SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.SNAPSHOT_ID); long sfSnapshotId = Long.parseLong(snapshotDetails.getValue()); SolidFireUtil.rollBackVolumeToSnapshot(sfConnection, sfVolumeId, sfSnapshotId); SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId); updateVolumeDetails(volumeVO.getId(), sfVolume.getTotalSize(), sfVolume.getScsiNaaDeviceId()); CommandResult commandResult = new CommandResult(); callback.complete(commandResult); }
VolumeInfo volumeInfo = snapshotInfo.getBaseVolume(); VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId()); SnapshotObjectTO snapshotObjectTo = (SnapshotObjectTO)snapshotInfo.getTO(); if (shouldTakeSnapshot(snapshotInfo.getId())) { String sfNewSnapshotName = volumeInfo.getName() + "-" + snapshotInfo.getUuid(); sfNewSnapshotName = StringUtils.left(volumeInfo.getName(), (volumeInfo.getName().length() - trimRequired)) + "-" + snapshotInfo.getUuid(); getSnapshotAttributes(snapshotInfo)); updateSnapshotDetails(snapshotInfo.getId(), volumeInfo.getId(), sfVolumeId, sfNewSnapshotId, storagePoolId, sfVolumeSize); String sfNewVolumeName = volumeInfo.getName() + "-" + snapshotInfo.getUuid(); updateSnapshotDetails(snapshotInfo.getId(), sfNewVolumeId, storagePoolId, sfVolumeSize, sfNewVolume.getIqn()); LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to take CloudStack snapshot: " + snapshotInfo.getId(), ex);
if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) { computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId()); boolean canStorageSystemCreateVolumeFromVolume = canStorageSystemCreateVolumeFromVolume(snapshotInfo.getDataStore().getId()); volumeDetail = new VolumeDetailVO(volumeInfo.getId(), "cloneOfSnapshot", String.valueOf(snapshotInfo.getId()), false); SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId()); if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { if (useCloning) { Map<String, String> extraDetails = null; if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { extraDetails = new HashMap<>(); String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK); if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) { disconnectHostFromVolume(hostVO, volumeInfo.getPoolId(), volumeInfo.get_iScsiName()); hostVO = getHost(snapshotInfo.getDataCenterId(), snapshotInfo.getHypervisorType(), false); else if (HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) { VolumeObjectTO newVolume = new VolumeObjectTO();
private void handleCreateNonManagedVolumeFromManagedSnapshot(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) { if (!HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) { String errMsg = "Creating a volume on non-managed storage from a snapshot on managed storage is currently only supported with XenServer."; snapshotInfo.processEvent(Event.CopyingRequested); HostVO hostVO = getHost(snapshotInfo.getDataCenterId(), HypervisorType.XenServer, true); int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value()); long snapshotStoragePoolId = snapshotInfo.getDataStore().getId(); DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary); HostVO hostVO = getHostInCluster(volumeStoragePoolVO.getClusterId()); long snapshotStoragePoolId = snapshotInfo.getDataStore().getId(); DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary); snapshotInfo.processEvent(Event.OperationSuccessed); snapshotInfo.processEvent(Event.OperationFailed);
private DataStore findSnapshotImageStore(SnapshotInfo snapshot) { Boolean fullSnapshot = true; Boolean snapshotFullBackup = snapshot.getFullBackup(); if (snapshotFullBackup != null) { fullSnapshot = snapshotFullBackup; } if (fullSnapshot) { return dataStoreMgr.getImageStore(snapshot.getDataCenterId()); } else { SnapshotInfo parentSnapshot = snapshot.getParent(); // Note that DataStore information in parentSnapshot is for primary // data store here, we need to // find the image store where the parent snapshot backup is located SnapshotDataStoreVO parentSnapshotOnBackupStore = null; if (parentSnapshot != null) { parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); } if (parentSnapshotOnBackupStore == null) { return dataStoreMgr.getImageStore(snapshot.getDataCenterId()); } return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), parentSnapshotOnBackupStore.getRole()); } }
private boolean usingBackendSnapshotFor(SnapshotInfo snapshotInfo) { String property = getSnapshotProperty(snapshotInfo.getId(), "takeSnapshot"); return Boolean.parseBoolean(property); }
private Map<String, String> getSnapshotDetails(SnapshotInfo snapshotInfo) { Map<String, String> snapshotDetails = new HashMap<>(); long storagePoolId = snapshotInfo.getDataStore().getId(); StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId); snapshotDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress()); snapshotDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort())); long snapshotId = snapshotInfo.getId(); snapshotDetails.put(DiskTO.IQN, getSnapshotProperty(snapshotId, DiskTO.IQN)); snapshotDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(snapshotInfo.getSize())); snapshotDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getSnapshotProperty(snapshotId, DiskTO.SCSI_NAA_DEVICE_ID)); snapshotDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_USERNAME)); snapshotDetails.put(DiskTO.CHAP_INITIATOR_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_SECRET)); snapshotDetails.put(DiskTO.CHAP_TARGET_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_USERNAME)); snapshotDetails.put(DiskTO.CHAP_TARGET_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_SECRET)); return snapshotDetails; }
public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { SnapshotInfo snapshotOnPrimary = null; Object payload = snapshot.getPayload(); CreateSnapshotPayload createSnapshotPayload = null; if (payload != null) { SnapshotVO snapshotVO = snapshotDao.acquireInLockTable(snapshot.getId()); if (snapshotVO == null) { throw new CloudRuntimeException("Failed to get lock on snapshot:" + snapshot.getId()); VolumeInfo volumeInfo = snapshot.getBaseVolume(); volumeInfo.stateTransit(Volume.Event.SnapshotRequested); SnapshotResult result = null; snapshotOnPrimary.addPayload(snapshot.getPayload()); } finally { if (snapshotVO != null) { snapshotDao.releaseFromLockTable(snapshot.getId());