Search in sources :

Example 26 with VolumeApiResult

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.

the class VolumeApiServiceImpl method liveMigrateVolume.

@DB
protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
    VolumeInfo vol = volFactory.getVolume(volume.getId());
    AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore) destPool);
    try {
        VolumeApiResult result = future.get();
        if (result.isFailed()) {
            s_logger.debug("migrate volume failed:" + result.getResult());
            throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
        }
        return result.getVolume();
    } catch (InterruptedException e) {
        s_logger.debug("migrate volume failed", e);
        throw new CloudRuntimeException(e.getMessage());
    } catch (ExecutionException e) {
        s_logger.debug("migrate volume failed", e);
        throw new CloudRuntimeException(e.getMessage());
    }
}
Also used : StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) ExecutionException(java.util.concurrent.ExecutionException) DB(com.cloud.utils.db.DB)

Example 27 with VolumeApiResult

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.

the class StorageManagerImpl method cleanupStorage.

@Override
public void cleanupStorage(boolean recurring) {
    GlobalLock scanLock = GlobalLock.getInternLock("storagemgr.cleanup");
    try {
        if (scanLock.lock(3)) {
            try {
                // Cleanup primary storage pools
                if (_templateCleanupEnabled) {
                    List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
                    for (StoragePoolVO pool : storagePools) {
                        try {
                            List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
                            s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName());
                            for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
                                if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
                                    s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId() + " because it is not completely downloaded.");
                                    continue;
                                }
                                if (!templatePoolVO.getMarkedForGC()) {
                                    templatePoolVO.setMarkedForGC(true);
                                    _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
                                    s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId() + " for garbage collection.");
                                    continue;
                                }
                                _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
                            }
                        } catch (Exception e) {
                            s_logger.warn("Problem cleaning up primary storage pool " + pool, e);
                        }
                    }
                }
                cleanupSecondaryStorage(recurring);
                List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long) StorageCleanupDelay.value() << 10)));
                for (VolumeVO vol : vols) {
                    try {
                        // If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
                        // system, but not necessary.
                        handleManagedStorage(vol);
                    } catch (Exception e) {
                        s_logger.warn("Unable to destroy host-side clustered file system " + vol.getUuid(), e);
                    }
                    try {
                        VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
                        if (volumeInfo != null) {
                            volService.expungeVolumeAsync(volumeInfo);
                        } else {
                            s_logger.debug("Volume " + vol.getUuid() + " is already destroyed");
                        }
                    } catch (Exception e) {
                        s_logger.warn("Unable to destroy volume " + vol.getUuid(), e);
                    }
                }
                // remove snapshots in Error state
                List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error);
                for (SnapshotVO snapshotVO : snapshots) {
                    try {
                        List<SnapshotDataStoreVO> storeRefs = _snapshotStoreDao.findBySnapshotId(snapshotVO.getId());
                        for (SnapshotDataStoreVO ref : storeRefs) {
                            _snapshotStoreDao.expunge(ref.getId());
                        }
                        _snapshotDao.expunge(snapshotVO.getId());
                    } catch (Exception e) {
                        s_logger.warn("Unable to destroy snapshot " + snapshotVO.getUuid(), e);
                    }
                }
                // destroy uploaded volumes in abandoned/error state
                List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
                for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
                    VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
                    if (volume == null) {
                        s_logger.warn("Uploaded volume with id " + volumeDataStore.getVolumeId() + " not found, so cannot be destroyed");
                        continue;
                    }
                    try {
                        DataStore dataStore = _dataStoreMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
                        EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
                        if (ep == null) {
                            s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded volume " + volume.getUuid());
                            continue;
                        }
                        Host host = _hostDao.findById(ep.getId());
                        if (host != null && host.getManagementServerId() != null) {
                            if (_serverId == host.getManagementServerId().longValue()) {
                                if (!volService.destroyVolume(volume.getId())) {
                                    s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid());
                                    continue;
                                }
                                // decrement volume resource count
                                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
                                // expunge volume from secondary if volume is on image store
                                VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
                                if (volOnSecondary != null) {
                                    s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
                                    AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
                                    VolumeApiResult result = future.get();
                                    if (!result.isSuccess()) {
                                        s_logger.warn("Failed to expunge volume " + volume.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
                                    }
                                }
                            }
                        }
                    } catch (Throwable th) {
                        s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
                    }
                }
                // destroy uploaded templates in abandoned/error state
                List<TemplateDataStoreVO> templateDataStores = _templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, VirtualMachineTemplate.State.UploadAbandoned);
                for (TemplateDataStoreVO templateDataStore : templateDataStores) {
                    VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
                    if (template == null) {
                        s_logger.warn("Uploaded template with id " + templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
                        continue;
                    }
                    try {
                        DataStore dataStore = _dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
                        EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
                        if (ep == null) {
                            s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded template " + template.getUuid());
                            continue;
                        }
                        Host host = _hostDao.findById(ep.getId());
                        if (host != null && host.getManagementServerId() != null) {
                            if (_serverId == host.getManagementServerId().longValue()) {
                                AsyncCallFuture<TemplateApiResult> future = _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), dataStore));
                                TemplateApiResult result = future.get();
                                if (!result.isSuccess()) {
                                    s_logger.warn("Failed to delete template " + template.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
                                    continue;
                                }
                                // remove from template_zone_ref
                                List<VMTemplateZoneVO> templateZones = _vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity) dataStore).getDataCenterId(), template.getId());
                                if (templateZones != null) {
                                    for (VMTemplateZoneVO templateZone : templateZones) {
                                        _vmTemplateZoneDao.remove(templateZone.getId());
                                    }
                                }
                                // mark all the occurrences of this template in the given store as destroyed
                                _templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
                                // find all eligible image stores for this template
                                List<DataStore> imageStores = _tmpltMgr.getImageStoreByTemplate(template.getId(), null);
                                if (imageStores == null || imageStores.size() == 0) {
                                    template.setState(VirtualMachineTemplate.State.Inactive);
                                    _templateDao.update(template.getId(), template);
                                    // decrement template resource count
                                    _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
                                }
                            }
                        }
                    } catch (Throwable th) {
                        s_logger.warn("Unable to destroy uploaded template " + template.getUuid() + ". Error details: " + th.getMessage());
                    }
                }
            } finally {
                scanLock.unlock();
            }
        }
    } finally {
        scanLock.releaseRef();
    }
}
Also used : VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) GlobalLock(com.cloud.utils.db.GlobalLock) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) VolumeDataStoreVO(org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO) SnapshotDataStoreVO(org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO) Host(com.cloud.host.Host) ManagementServerHost(com.cloud.cluster.ManagementServerHost) TemplateDataStoreVO(org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO) ConnectionException(com.cloud.exception.ConnectionException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) StorageConflictException(com.cloud.exception.StorageConflictException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnknownHostException(java.net.UnknownHostException) ExecutionException(java.util.concurrent.ExecutionException) ResourceInUseException(com.cloud.exception.ResourceInUseException) URISyntaxException(java.net.URISyntaxException) DiscoveryException(com.cloud.exception.DiscoveryException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) Date(java.util.Date) TemplateApiResult(org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult)

Example 28 with VolumeApiResult

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.

the class VolumeApiServiceImpl method orchestrateExtractVolume.

private String orchestrateExtractVolume(long volumeId, long zoneId) {
    // get latest volume state to make sure that it is not updated by other parallel operations
    VolumeVO volume = _volsDao.findById(volumeId);
    if (volume == null || volume.getState() != Volume.State.Ready) {
        throw new InvalidParameterValueException("Volume to be extracted has been removed or not in right state!");
    }
    // perform extraction
    ImageStoreEntity secStore = (ImageStoreEntity) dataStoreMgr.getImageStore(zoneId);
    String value = _configDao.getValue(Config.CopyVolumeWait.toString());
    NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
    // Copy volume from primary to secondary storage
    VolumeInfo srcVol = volFactory.getVolume(volumeId);
    AsyncCallFuture<VolumeApiResult> cvAnswer = volService.copyVolume(srcVol, secStore);
    // Check if you got a valid answer.
    VolumeApiResult cvResult = null;
    try {
        cvResult = cvAnswer.get();
    } catch (InterruptedException e1) {
        s_logger.debug("failed copy volume", e1);
        throw new CloudRuntimeException("Failed to copy volume", e1);
    } catch (ExecutionException e1) {
        s_logger.debug("failed copy volume", e1);
        throw new CloudRuntimeException("Failed to copy volume", e1);
    }
    if (cvResult == null || cvResult.isFailed()) {
        String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage.";
        throw new CloudRuntimeException(errorString);
    }
    VolumeInfo vol = cvResult.getVolume();
    String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat(), vol);
    VolumeDataStoreVO volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
    volumeStoreRef.setExtractUrl(extractUrl);
    volumeStoreRef.setExtractUrlCreated(DateUtil.now());
    _volumeStoreDao.update(volumeStoreRef.getId(), volumeStoreRef);
    return extractUrl;
}
Also used : InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeDataStoreVO(org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO) ImageStoreEntity(org.apache.cloudstack.storage.image.datastore.ImageStoreEntity) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) ExecutionException(java.util.concurrent.ExecutionException)

Example 29 with VolumeApiResult

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.

the class VolumeApiServiceImpl method orchestrateResizeVolume.

private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, Long newDiskOfferingId, boolean shrinkOk) {
    VolumeVO volume = _volsDao.findById(volumeId);
    UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
    StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
    boolean isManaged = storagePool.isManaged();
    /*
         * get a list of hosts to send the commands to, try the system the
         * associated vm is running on first, then the last known place it ran.
         * If not attached to a userVm, we pass 'none' and resizevolume.sh is ok
         * with that since it only needs the vm name to live resize
         */
    long[] hosts = null;
    String instanceName = "none";
    if (userVm != null) {
        instanceName = userVm.getInstanceName();
        if (userVm.getHostId() != null) {
            hosts = new long[] { userVm.getHostId() };
        } else if (userVm.getLastHostId() != null) {
            hosts = new long[] { userVm.getLastHostId() };
        }
        final String errorMsg = "The VM must be stopped or the disk detached in order to resize with the XenServer Hypervisor.";
        if (storagePool.isManaged() && storagePool.getHypervisor() == HypervisorType.Any && hosts != null && hosts.length > 0) {
            HostVO host = _hostDao.findById(hosts[0]);
            if (currentSize != newSize && host.getHypervisorType() == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
                throw new InvalidParameterValueException(errorMsg);
            }
        }
        /* Xen only works offline, SR does not support VDI.resizeOnline */
        if (currentSize != newSize && _volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
            throw new InvalidParameterValueException(errorMsg);
        }
    }
    ResizeVolumePayload payload = new ResizeVolumePayload(newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk, instanceName, hosts, isManaged);
    try {
        VolumeInfo vol = volFactory.getVolume(volume.getId());
        vol.addPayload(payload);
        // this call to resize has a different impact depending on whether the
        // underlying primary storage is managed or not
        // if managed, this is the chance for the plug-in to change IOPS value, if applicable
        // if not managed, this is the chance for the plug-in to talk to the hypervisor layer
        // to change the size of the disk
        AsyncCallFuture<VolumeApiResult> future = volService.resize(vol);
        VolumeApiResult result = future.get();
        // needs to tell the hypervisor to resize the disk
        if (storagePool.isManaged() && currentSize != newSize) {
            if (hosts != null && hosts.length > 0) {
                volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName);
            }
            volume.setSize(newSize);
            _volsDao.update(volume.getId(), volume);
        }
        if (result.isFailed()) {
            s_logger.warn("Failed to resize the volume " + volume);
            String details = "";
            if (result.getResult() != null && !result.getResult().isEmpty()) {
                details = result.getResult();
            }
            throw new CloudRuntimeException(details);
        }
        volume = _volsDao.findById(volume.getId());
        if (newDiskOfferingId != null) {
            volume.setDiskOfferingId(newDiskOfferingId);
        }
        if (currentSize != newSize) {
            volume.setSize(newSize);
        }
        _volsDao.update(volume.getId(), volume);
        /* Update resource count for the account on primary storage resource */
        if (!shrinkOk) {
            _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize));
        } else {
            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(currentSize - newSize));
        }
        return volume;
    } catch (InterruptedException e) {
        s_logger.warn("failed get resize volume result", e);
        throw new CloudRuntimeException(e.getMessage());
    } catch (ExecutionException e) {
        s_logger.warn("failed get resize volume result", e);
        throw new CloudRuntimeException(e.getMessage());
    } catch (Exception e) {
        s_logger.warn("failed get resize volume result", e);
        throw new CloudRuntimeException(e.getMessage());
    }
}
Also used : UserVmVO(com.cloud.vm.UserVmVO) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) HostVO(com.cloud.host.HostVO) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) JsonParseException(com.google.gson.JsonParseException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) MalformedURLException(java.net.MalformedURLException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

VolumeApiResult (org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult)29 ExecutionException (java.util.concurrent.ExecutionException)23 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)22 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)17 VolumeVO (com.cloud.storage.VolumeVO)16 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)14 DB (com.cloud.utils.db.DB)9 Test (org.testng.annotations.Test)8 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)7 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)7 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)6 StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)5 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)4 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)4 HostVO (com.cloud.host.HostVO)4 NoTransitionException (com.cloud.utils.fsm.NoTransitionException)4 TemplateInfo (org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo)4 PermissionDeniedException (com.cloud.exception.PermissionDeniedException)3 Host (com.cloud.host.Host)3 SnapshotVO (com.cloud.storage.SnapshotVO)3