Search in sources :

Example 26 with VolumeInfo

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

the class VolumeServiceImpl method registerVolume.

@Override
public AsyncCallFuture<VolumeApiResult> registerVolume(final VolumeInfo volume, final DataStore store) {
    final AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<>();
    final DataObject volumeOnStore = store.create(volume);
    volumeOnStore.processEvent(Event.CreateOnlyRequested);
    try {
        final CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<>(null, volumeOnStore, future);
        final AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
        caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
        caller.setContext(context);
        store.getDriver().createAsync(store, volumeOnStore, caller);
    } catch (final CloudRuntimeException ex) {
        // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
        final VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
        if (volStoreVO != null) {
            final VolumeInfo volObj = volFactory.getVolume(volume, store);
            volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
        }
        final VolumeApiResult res = new VolumeApiResult((VolumeObject) volumeOnStore);
        res.setResult(ex.getMessage());
        future.complete(res);
    }
    return future;
}
Also used : VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) CreateCmdResult(com.cloud.engine.subsystem.api.storage.CreateCmdResult) AsyncCallFuture(com.cloud.framework.async.AsyncCallFuture) DataObject(com.cloud.engine.subsystem.api.storage.DataObject) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeDataStoreVO(com.cloud.storage.datastore.db.VolumeDataStoreVO)

Example 27 with VolumeInfo

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

the class StorageSystemSnapshotStrategy method takeSnapshot.

@Override
@DB
public SnapshotInfo takeSnapshot(final SnapshotInfo snapshotInfo) {
    final VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
    if (volumeInfo.getFormat() != ImageFormat.VHD) {
        throw new CloudRuntimeException("Only the " + ImageFormat.VHD.toString() + " image type is currently supported.");
    }
    final SnapshotVO snapshotVO = _snapshotDao.acquireInLockTable(snapshotInfo.getId());
    if (snapshotVO == null) {
        throw new CloudRuntimeException("Failed to acquire lock on the following snapshot: " + snapshotInfo.getId());
    }
    SnapshotResult result = null;
    try {
        volumeInfo.stateTransit(Volume.Event.SnapshotRequested);
        // 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());
            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)
        performSnapshotAndCopyOnHostSide(volumeInfo, snapshotInfo);
        markAsBackedUp((SnapshotObject) result.getSnashot());
    } finally {
        if (result != null && result.isSuccess()) {
            volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
        } else {
            volumeInfo.stateTransit(Volume.Event.OperationFailed);
        }
        _snapshotDao.releaseFromLockTable(snapshotInfo.getId());
    }
    return snapshotInfo;
}
Also used : SnapshotVO(com.cloud.storage.SnapshotVO) SnapshotResult(com.cloud.engine.subsystem.api.storage.SnapshotResult) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) DB(com.cloud.utils.db.DB)

Example 28 with VolumeInfo

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

the class TemplateManagerImpl method createPrivateTemplate.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
public VirtualMachineTemplate createPrivateTemplate(final CreateTemplateCmd command) throws CloudRuntimeException {
    final long templateId = command.getEntityId();
    final Long volumeId = command.getVolumeId();
    final Long snapshotId = command.getSnapshotId();
    VMTemplateVO privateTemplate = null;
    final Long accountId = CallContext.current().getCallingAccountId();
    SnapshotVO snapshot = null;
    VolumeVO volume = null;
    try {
        final TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
        long zoneId = 0;
        if (snapshotId != null) {
            snapshot = _snapshotDao.findById(snapshotId);
            zoneId = snapshot.getDataCenterId();
        } else if (volumeId != null) {
            volume = _volumeDao.findById(volumeId);
            zoneId = volume.getDataCenterId();
        }
        DataStore store = _dataStoreMgr.getImageStore(zoneId);
        if (store == null) {
            throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
        }
        final AsyncCallFuture<TemplateApiResult> future;
        if (snapshotId != null) {
            final DataStoreRole dataStoreRole = ApiResponseHelper.getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
            SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
            if (dataStoreRole == DataStoreRole.Image) {
                if (snapInfo == null) {
                    snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
                    if (snapInfo == null) {
                        throw new CloudRuntimeException("Cannot find snapshot " + snapshotId);
                    }
                    // 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(snapshotId, dataStoreRole);
                    if (snapInfo == null) {
                        throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + " on secondary and could not create backup");
                    }
                }
                final DataStore snapStore = snapInfo.getDataStore();
                if (snapStore != null) {
                    // pick snapshot image store to create template
                    store = snapStore;
                }
            }
            future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store);
        } else if (volumeId != null) {
            final VolumeInfo volInfo = _volFactory.getVolume(volumeId);
            future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
        } else {
            throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
        }
        final CommandResult result;
        try {
            result = future.get();
            if (result.isFailed()) {
                privateTemplate = null;
                s_logger.debug("Failed to create template" + result.getResult());
                throw new CloudRuntimeException("Failed to create template" + result.getResult());
            }
            // create entries in template_zone_ref table
            if (_dataStoreMgr.isRegionStore(store)) {
                // template created on region store
                _tmpltSvr.associateTemplateToZone(templateId, null);
            } else {
                final VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
                _tmpltZoneDao.persist(templateZone);
            }
            privateTemplate = _tmpltDao.findById(templateId);
        } catch (final InterruptedException | ExecutionException e) {
            s_logger.debug("Failed to create template", e);
            throw new CloudRuntimeException("Failed to create template", e);
        }
    } finally {
        if (privateTemplate == null) {
            final VolumeVO volumeFinal = volume;
            final SnapshotVO snapshotFinal = snapshot;
            Transaction.execute(new TransactionCallbackNoReturn() {

                @Override
                public void doInTransactionWithoutResult(final TransactionStatus status) {
                    // template_store_ref entries should have been removed using our
                    // DataObject.processEvent command in case of failure, but clean
                    // it up here to avoid
                    // some leftovers which will cause removing template from
                    // vm_template table fail.
                    _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
                    // Remove the template_zone_ref record
                    _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
                    // Remove the template record
                    _tmpltDao.expunge(templateId);
                    // decrement resource count
                    if (accountId != null) {
                        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
                        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize() : snapshotFinal.getSize()));
                    }
                }
            });
        }
    }
    if (privateTemplate != null) {
        return privateTemplate;
    } else {
        throw new CloudRuntimeException("Failed to create a template");
    }
}
Also used : VMTemplateZoneVO(com.cloud.storage.VMTemplateZoneVO) VMTemplateVO(com.cloud.storage.VMTemplateVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) TemplateApiResult(com.cloud.engine.subsystem.api.storage.TemplateService.TemplateApiResult) Date(java.util.Date) CommandResult(com.cloud.storage.command.CommandResult) DataStoreRole(com.cloud.storage.DataStoreRole) TemplateInfo(com.cloud.engine.subsystem.api.storage.TemplateInfo) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) VolumeVO(com.cloud.storage.VolumeVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) ExecutionException(java.util.concurrent.ExecutionException) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 29 with VolumeInfo

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

the class VolumeOrchestrator method migrateVolume.

@Override
@DB
public Volume migrateVolume(final Volume volume, final StoragePool destPool) throws StorageUnavailableException {
    final VolumeInfo vol = volFactory.getVolume(volume.getId());
    final AsyncCallFuture<VolumeService.VolumeApiResult> future = volService.copyVolume(vol, (DataStore) destPool);
    try {
        final VolumeService.VolumeApiResult result = future.get();
        if (result.isFailed()) {
            s_logger.error("Migrate volume failed. Error received from hypervisor:" + result.getResult());
            throw new StorageUnavailableException("Migrate volume failed. Error received from hypervisor: " + result.getResult(), destPool.getId());
        } else {
            // update the volumeId for snapshots on secondary
            if (!_snapshotDao.listByVolumeId(vol.getId()).isEmpty()) {
                _snapshotDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
                _snapshotDataStoreDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
            }
        }
        return result.getVolume();
    } catch (final InterruptedException e) {
        s_logger.debug("migrate volume failed", e);
        throw new CloudRuntimeException(e.getMessage());
    } catch (final ExecutionException e) {
        s_logger.debug("migrate volume failed", e);
        throw new CloudRuntimeException(e.getMessage());
    }
}
Also used : StorageUnavailableException(com.cloud.exception.StorageUnavailableException) VolumeService(com.cloud.engine.subsystem.api.storage.VolumeService) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) ExecutionException(java.util.concurrent.ExecutionException) DB(com.cloud.utils.db.DB)

Example 30 with VolumeInfo

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

the class VolumeOrchestrator method recreateVolume.

private Pair<VolumeVO, DataStore> recreateVolume(final VolumeVO vol, final VirtualMachineProfile vm, final DeployDestination dest) throws StorageUnavailableException {
    VolumeVO newVol;
    final boolean recreate = RecreatableSystemVmEnabled.value();
    DataStore destPool = null;
    if (recreate && (dest.getStorageForDisks() == null || dest.getStorageForDisks().get(vol) == null)) {
        destPool = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
        s_logger.debug("existing pool: " + destPool.getId());
    } else {
        final StoragePool pool = dest.getStorageForDisks().get(vol);
        destPool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
    }
    if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
        newVol = vol;
    } else {
        newVol = switchVolume(vol, vm);
        // changed
        if (dest.getStorageForDisks() != null && dest.getStorageForDisks().containsKey(vol)) {
            final StoragePool poolWithOldVol = dest.getStorageForDisks().get(vol);
            dest.getStorageForDisks().put(newVol, poolWithOldVol);
            dest.getStorageForDisks().remove(vol);
        }
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Created new volume " + newVol + " for old volume " + vol);
        }
    }
    VolumeInfo volume = volFactory.getVolume(newVol.getId(), destPool);
    final Long templateId = newVol.getTemplateId();
    for (int i = 0; i < 2; i++) {
        // retry one more time in case of template reload is required for Vmware case
        AsyncCallFuture<VolumeService.VolumeApiResult> future = null;
        if (templateId == null) {
            final DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
            final HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
            // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
            volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
            volume = volFactory.getVolume(newVol.getId(), destPool);
            future = volService.createVolumeAsync(volume, destPool);
        } else {
            final TemplateInfo templ = tmplFactory.getReadyTemplateOnImageStore(templateId, dest.getZone().getId());
            if (templ == null) {
                s_logger.debug("can't find ready template: " + templateId + " for data center " + dest.getZone().getId());
                throw new CloudRuntimeException("can't find ready template: " + templateId + " for data center " + dest.getZone().getId());
            }
            final PrimaryDataStore primaryDataStore = (PrimaryDataStore) destPool;
            if (primaryDataStore.isManaged()) {
                final DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
                final HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
                // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
                volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
                final long hostId = vm.getVirtualMachine().getHostId();
                future = volService.createManagedStorageAndVolumeFromTemplateAsync(volume, destPool.getId(), templ, hostId);
            } else {
                future = volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
            }
        }
        VolumeService.VolumeApiResult result = null;
        try {
            result = future.get();
            if (result.isFailed()) {
                if (result.getResult().contains("request template reload") && (i == 0)) {
                    s_logger.debug("Retry template re-deploy for vmware");
                    continue;
                } else {
                    s_logger.debug("Unable to create " + newVol + ":" + result.getResult());
                    throw new StorageUnavailableException("Unable to create " + newVol + ":" + result.getResult(), destPool.getId());
                }
            }
            final StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId());
            if (storagePool.isManaged()) {
                final long hostId = vm.getVirtualMachine().getHostId();
                final Host host = _hostDao.findById(hostId);
                volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
            }
            newVol = _volsDao.findById(newVol.getId());
            // break out of template-redeploy retry loop
            break;
        } catch (final InterruptedException e) {
            s_logger.error("Unable to create " + newVol, e);
            throw new StorageUnavailableException("Unable to create " + newVol + ":" + e.toString(), destPool.getId());
        } catch (final ExecutionException e) {
            s_logger.error("Unable to create " + newVol, e);
            throw new StorageUnavailableException("Unable to create " + newVol + ":" + e.toString(), destPool.getId());
        }
    }
    return new Pair<>(newVol, destPool);
}
Also used : StoragePool(com.cloud.storage.StoragePool) DiskOffering(com.cloud.offering.DiskOffering) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) Host(com.cloud.host.Host) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) TemplateInfo(com.cloud.engine.subsystem.api.storage.TemplateInfo) 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) PrimaryDataStore(com.cloud.engine.subsystem.api.storage.PrimaryDataStore) Pair(com.cloud.utils.Pair)

Aggregations

VolumeInfo (com.cloud.engine.subsystem.api.storage.VolumeInfo)63 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)39 ExecutionException (java.util.concurrent.ExecutionException)26 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)21 DataStore (com.cloud.engine.subsystem.api.storage.DataStore)19 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)19 InvalidParameterValueException (com.cloud.utils.exception.InvalidParameterValueException)17 VolumeVO (com.cloud.storage.VolumeVO)14 CopyCommandResult (com.cloud.engine.subsystem.api.storage.CopyCommandResult)12 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)12 DB (com.cloud.utils.db.DB)12 StoragePoolVO (com.cloud.storage.datastore.db.StoragePoolVO)9 Account (com.cloud.user.Account)9 ArrayList (java.util.ArrayList)9 PrimaryDataStore (com.cloud.engine.subsystem.api.storage.PrimaryDataStore)8 SnapshotInfo (com.cloud.engine.subsystem.api.storage.SnapshotInfo)8 ActionEvent (com.cloud.event.ActionEvent)8 VolumeDataStoreVO (com.cloud.storage.datastore.db.VolumeDataStoreVO)8 AsyncCallFuture (com.cloud.framework.async.AsyncCallFuture)7 StoragePool (com.cloud.storage.StoragePool)7