Search in sources :

Example 1 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class SnapshotManagerImpl method revertSnapshot.

@Override
public Snapshot revertSnapshot(final Long snapshotId) {
    final SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
    if (snapshot == null) {
        throw new InvalidParameterValueException("No such snapshot");
    }
    final VolumeVO volume = _volsDao.findById(snapshot.getVolumeId());
    if (volume.getState() != Volume.State.Ready) {
        throw new InvalidParameterValueException("The volume is not in Ready state.");
    }
    final Long instanceId = volume.getInstanceId();
    // in order to revert the volume
    if (instanceId != null) {
        final UserVmVO vm = _vmDao.findById(instanceId);
        if (vm.getState() != State.Stopped && vm.getState() != State.Shutdowned) {
            throw new InvalidParameterValueException("The VM the specified disk is attached to is not in the shutdown state.");
        }
        // If target VM has associated VM snapshots then don't allow to revert from snapshot
        final List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(instanceId);
        if (vmSnapshots.size() > 0) {
            throw new InvalidParameterValueException("Unable to revert snapshot for VM, please remove VM snapshots before reverting VM from snapshot");
        }
    }
    final SnapshotInfo snapshotInfo = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
    if (snapshotInfo == null) {
        throw new CloudRuntimeException("snapshot:" + snapshotId + " not exist in data store");
    }
    final SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.REVERT);
    if (snapshotStrategy == null) {
        s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
        return null;
    }
    final boolean result = snapshotStrategy.revertSnapshot(snapshotInfo);
    if (result) {
        // update volume size and primary storage count
        _resourceLimitMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.primary_storage, volume.getSize() - snapshot.getSize());
        volume.setSize(snapshot.getSize());
        _volsDao.update(volume.getId(), volume);
        return snapshotInfo;
    }
    return null;
}
Also used : VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) UserVmVO(com.cloud.vm.UserVmVO) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) SnapshotVO(com.cloud.storage.SnapshotVO) VolumeVO(com.cloud.storage.VolumeVO) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy)

Example 2 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class SnapshotManagerImpl method takeSnapshot.

@Override
@DB
public SnapshotInfo takeSnapshot(final VolumeInfo volume) throws ResourceAllocationException {
    final CreateSnapshotPayload payload = (CreateSnapshotPayload) volume.getpayload();
    final Long snapshotId = payload.getSnapshotId();
    final Account snapshotOwner = payload.getAccount();
    final SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, volume.getDataStore());
    snapshot.addPayload(payload);
    try {
        final SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
        if (snapshotStrategy == null) {
            throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId);
        }
        snapshotStrategy.takeSnapshot(snapshot);
        try {
            SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Image);
            if (snapshotStoreRef == null) {
                // The snapshot was not backed up to secondary.  Find the snap on primary
                snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
                if (snapshotStoreRef == null) {
                    throw new CloudRuntimeException("Could not find snapshot");
                }
            }
            // Correct the resource count of snapshot in case of delta snapshots.
            _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize() - snapshotStoreRef.getPhysicalSize()));
        } catch (final Exception e) {
            s_logger.debug("post process snapshot failed", e);
        }
    } catch (final Exception e) {
        s_logger.debug("Failed to create snapshot", e);
        _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
        _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize()));
        throw new CloudRuntimeException("Failed to create snapshot", e);
    }
    return snapshot;
}
Also used : Account(com.cloud.user.Account) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SnapshotDataStoreVO(com.cloud.storage.datastore.db.SnapshotDataStoreVO) CreateSnapshotPayload(com.cloud.storage.CreateSnapshotPayload) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DB(com.cloud.utils.db.DB)

Example 3 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class SnapshotManagerImpl method backupSnapshotFromVmSnapshot.

@Override
public Snapshot backupSnapshotFromVmSnapshot(final Long snapshotId, final Long vmId, final Long volumeId, final Long vmSnapshotId) {
    final VMInstanceVO vm = _vmDao.findById(vmId);
    if (vm == null) {
        throw new InvalidParameterValueException("Creating snapshot failed due to vm:" + vmId + " doesn't exist");
    }
    if (!HypervisorType.KVM.equals(vm.getHypervisorType())) {
        throw new InvalidParameterValueException("Unsupported hypervisor type " + vm.getHypervisorType() + ". This supports KVM only");
    }
    final VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
    if (vmSnapshot == null) {
        throw new InvalidParameterValueException("Creating snapshot failed due to vmSnapshot:" + vmSnapshotId + " doesn't exist");
    }
    // check vmsnapshot permissions
    final Account caller = CallContext.current().getCallingAccount();
    _accountMgr.checkAccess(caller, null, true, vmSnapshot);
    final SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
    if (snapshot == null) {
        throw new InvalidParameterValueException("Creating snapshot failed due to snapshot:" + snapshotId + " doesn't exist");
    }
    final VolumeInfo volume = volFactory.getVolume(volumeId);
    if (volume == null) {
        throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
    }
    if (volume.getState() != Volume.State.Ready) {
        throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
    }
    final DataStore store = volume.getDataStore();
    final SnapshotDataStoreVO parentSnapshotDataStoreVO = _snapshotStoreDao.findParent(store.getRole(), store.getId(), volumeId);
    if (parentSnapshotDataStoreVO != null) {
        // Double check the snapshot is removed or not
        final SnapshotVO parentSnap = _snapshotDao.findById(parentSnapshotDataStoreVO.getSnapshotId());
        if (parentSnap != null && parentSnapshotDataStoreVO.getInstallPath() != null && parentSnapshotDataStoreVO.getInstallPath().equals(vmSnapshot.getName())) {
            throw new InvalidParameterValueException("Creating snapshot failed due to snapshot : " + parentSnap.getUuid() + " is created from the same vm snapshot");
        }
    }
    SnapshotInfo snapshotInfo = this.snapshotFactory.getSnapshot(snapshotId, store);
    snapshotInfo = (SnapshotInfo) store.create(snapshotInfo);
    final SnapshotDataStoreVO snapshotOnPrimaryStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), store.getRole());
    snapshotOnPrimaryStore.setState(ObjectInDataStoreStateMachine.State.Ready);
    snapshotOnPrimaryStore.setInstallPath(vmSnapshot.getName());
    _snapshotStoreDao.update(snapshotOnPrimaryStore.getId(), snapshotOnPrimaryStore);
    snapshot.setState(Snapshot.State.CreatedOnPrimary);
    _snapshotDao.update(snapshot.getId(), snapshot);
    snapshotInfo = this.snapshotFactory.getSnapshot(snapshotId, store);
    final Long snapshotOwnerId = vm.getAccountId();
    try {
        final SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
        if (snapshotStrategy == null) {
            throw new CloudRuntimeException("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
        }
        snapshotInfo = snapshotStrategy.backupSnapshot(snapshotInfo);
    } catch (final Exception e) {
        s_logger.debug("Failed to backup snapshot from vm snapshot", e);
        _resourceLimitMgr.decrementResourceCount(snapshotOwnerId, ResourceType.snapshot);
        _resourceLimitMgr.decrementResourceCount(snapshotOwnerId, ResourceType.secondary_storage, volume.getSize());
        throw new CloudRuntimeException("Failed to backup snapshot from vm snapshot", e);
    }
    return snapshotInfo;
}
Also used : Account(com.cloud.user.Account) SnapshotDataStoreVO(com.cloud.storage.datastore.db.SnapshotDataStoreVO) VMInstanceVO(com.cloud.vm.VMInstanceVO) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) SnapshotVO(com.cloud.storage.SnapshotVO) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy)

Example 4 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class SnapshotManagerImpl method createSnapshot.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "creating snapshot", async = true)
public Snapshot createSnapshot(final Long volumeId, final Long policyId, final Long snapshotId, final Account snapshotOwner) {
    final VolumeInfo volume = volFactory.getVolume(volumeId);
    if (volume == null) {
        throw new InvalidParameterValueException("No such volume exist");
    }
    if (volume.getState() != Volume.State.Ready) {
        throw new InvalidParameterValueException("Volume is not in ready state");
    }
    // does the caller have the authority to act on this volume
    _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
    final SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
    if (snapshot == null) {
        s_logger.debug("Failed to create snapshot");
        throw new CloudRuntimeException("Failed to create snapshot");
    }
    try {
        _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
    } catch (final Exception e) {
        s_logger.debug("Failed to create snapshot", e);
        throw new CloudRuntimeException("Failed to create snapshot", e);
    }
    return snapshot;
}
Also used : SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 5 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class VolumeOrchestrator method createVolumeFromSnapshot.

@DB
@Override
public VolumeInfo createVolumeFromSnapshot(final Volume volume, final Snapshot snapshot, final UserVm vm) throws StorageUnavailableException {
    final Account account = _entityMgr.findById(Account.class, volume.getAccountId());
    final HashSet<StoragePool> poolsToAvoid = new HashSet<>();
    StoragePool pool = null;
    final Set<Long> podsToAvoid = new HashSet<>();
    Pair<Pod, Long> pod = null;
    final DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
    final DataCenter dc = _entityMgr.findById(DataCenter.class, volume.getDataCenterId());
    final DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
    String msg = "There are no available storage pools to store the volume in";
    if (vm != null) {
        final Pod podofVM = _entityMgr.findById(Pod.class, vm.getPodIdToDeployIn());
        if (podofVM != null) {
            pod = new Pair<>(podofVM, podofVM.getId());
        }
    }
    if (vm != null && pod != null) {
        // if VM is running use the hostId to find the clusterID. If it is stopped, refer the cluster where the ROOT volume of the VM exists.
        Long hostId = null;
        Long clusterId = null;
        if (vm.getState() == State.Running) {
            hostId = vm.getHostId();
            if (hostId != null) {
                final Host vmHost = _entityMgr.findById(Host.class, hostId);
                clusterId = vmHost.getClusterId();
            }
        } else {
            final List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
            if (rootVolumesOfVm.size() != 1) {
                throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state. Please contact Cloud Support.");
            } else {
                final VolumeVO rootVolumeOfVm = rootVolumesOfVm.get(0);
                final StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
                clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
            }
        }
        // Determine what storage pool to store the volume in
        while ((pool = findStoragePool(dskCh, dc, pod.first(), clusterId, hostId, vm, poolsToAvoid)) != null) {
            break;
        }
        if (pool == null) {
            // pool could not be found in the VM's pod/cluster.
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Could not find any storage pool to create Volume in the pod/cluster of the provided VM " + vm.getUuid());
            }
            final StringBuilder addDetails = new StringBuilder(msg);
            addDetails.append(", Could not find any storage pool to create Volume in the pod/cluster of the VM ");
            addDetails.append(vm.getUuid());
            msg = addDetails.toString();
        }
    } else {
        // Determine what pod to store the volume in
        while ((pod = findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
            podsToAvoid.add(pod.first().getId());
            // Determine what storage pool to store the volume in
            while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) {
                break;
            }
            if (pool != null) {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Found a suitable pool for create volume: " + pool.getId());
                }
                break;
            }
        }
    }
    if (pool == null) {
        s_logger.info(msg);
        throw new StorageUnavailableException(msg, -1);
    }
    final VolumeInfo vol = volFactory.getVolume(volume.getId());
    final DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
    final DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
    SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
    if (snapInfo == null && dataStoreRole == DataStoreRole.Image) {
        // snapshot is not backed up to secondary, let's do that now.
        snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
        if (snapInfo == null) {
            throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId());
        }
        // We need to copy the snapshot onto secondary.
        final SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
        snapshotStrategy.backupSnapshot(snapInfo);
        // Attempt to grab it again.
        snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
        if (snapInfo == null) {
            throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
        }
    }
    // don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
    if (!DataStoreRole.Primary.equals(dataStoreRole)) {
        try {
            // sync snapshot to region store if necessary
            final DataStore snapStore = snapInfo.getDataStore();
            final long snapVolId = snapInfo.getVolumeId();
            _snapshotSrv.syncVolumeSnapshotsToRegionStore(snapVolId, snapStore);
        } catch (final Exception ex) {
            // log but ignore the sync error to avoid any potential S3 down issue, it should be sync next time
            s_logger.warn(ex.getMessage(), ex);
        }
    }
    // create volume on primary from snapshot
    final AsyncCallFuture<VolumeService.VolumeApiResult> future = volService.createVolumeFromSnapshot(vol, store, snapInfo);
    try {
        final VolumeService.VolumeApiResult result = future.get();
        if (result.isFailed()) {
            s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
            throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
        }
        return result.getVolume();
    } catch (final InterruptedException e) {
        s_logger.debug("Failed to create volume from snapshot", e);
        throw new CloudRuntimeException("Failed to create volume from snapshot", e);
    } catch (final ExecutionException e) {
        s_logger.debug("Failed to create volume from snapshot", e);
        throw new CloudRuntimeException("Failed to create volume from snapshot", e);
    }
}
Also used : Account(com.cloud.user.Account) StoragePool(com.cloud.storage.StoragePool) DiskOffering(com.cloud.offering.DiskOffering) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) DataStoreRole(com.cloud.storage.DataStoreRole) VolumeVO(com.cloud.storage.VolumeVO) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeService(com.cloud.engine.subsystem.api.storage.VolumeService) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) PrimaryDataStore(com.cloud.engine.subsystem.api.storage.PrimaryDataStore) StoragePoolVO(com.cloud.storage.datastore.db.StoragePoolVO) ExecutionException(java.util.concurrent.ExecutionException) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy) HashSet(java.util.HashSet) Pod(com.cloud.dc.Pod) Host(com.cloud.host.Host) DiskProfile(com.cloud.vm.DiskProfile) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) InsufficientStorageCapacityException(com.cloud.exception.InsufficientStorageCapacityException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) DataCenter(com.cloud.dc.DataCenter) DB(com.cloud.utils.db.DB)

Aggregations

SnapshotInfo (com.cloud.engine.subsystem.api.storage.SnapshotInfo)28 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)20 NoTransitionException (com.cloud.utils.fsm.NoTransitionException)10 ExecutionException (java.util.concurrent.ExecutionException)10 DataStore (com.cloud.engine.subsystem.api.storage.DataStore)9 SnapshotDataStoreVO (com.cloud.storage.datastore.db.SnapshotDataStoreVO)9 InvalidParameterValueException (com.cloud.utils.exception.InvalidParameterValueException)9 SnapshotResult (com.cloud.engine.subsystem.api.storage.SnapshotResult)8 VolumeInfo (com.cloud.engine.subsystem.api.storage.VolumeInfo)8 CopyCommandResult (com.cloud.engine.subsystem.api.storage.CopyCommandResult)7 DB (com.cloud.utils.db.DB)7 SnapshotVO (com.cloud.storage.SnapshotVO)6 SnapshotStrategy (com.cloud.engine.subsystem.api.storage.SnapshotStrategy)5 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)5 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)4 VolumeVO (com.cloud.storage.VolumeVO)4 CommandResult (com.cloud.storage.command.CommandResult)4 ConfigurationException (javax.naming.ConfigurationException)4 Answer (com.cloud.agent.api.Answer)3 MigrateVolumeAnswer (com.cloud.agent.api.storage.MigrateVolumeAnswer)3