Search in sources :

Example 1 with VolumeObjectTO

use of org.apache.cloudstack.storage.to.VolumeObjectTO in project cloudstack by apache.

the class VolumeServiceImpl method handleVolumeSync.

@Override
public void handleVolumeSync(DataStore store) {
    if (store == null) {
        s_logger.warn("Huh? image store is null");
        return;
    }
    long storeId = store.getId();
    // add lock to make template sync for a data store only be done once
    String lockString = "volumesync.storeId:" + storeId;
    GlobalLock syncLock = GlobalLock.getInternLock(lockString);
    try {
        if (syncLock.lock(3)) {
            try {
                Map<Long, TemplateProp> volumeInfos = listVolume(store);
                if (volumeInfos == null) {
                    return;
                }
                // find all the db volumes including those with NULL url column to avoid accidentally deleting volumes on image store later.
                List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
                List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
                for (VolumeDataStoreVO volumeStore : dbVolumes) {
                    VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
                    if (volume == null) {
                        s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
                        volumeStore.setDestroyed(true);
                        _volumeStoreDao.update(volumeStore.getId(), volumeStore);
                        continue;
                    }
                    // Exists then don't download
                    if (volumeInfos.containsKey(volume.getId())) {
                        TemplateProp volInfo = volumeInfos.remove(volume.getId());
                        toBeDownloaded.remove(volumeStore);
                        s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
                        if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
                            volumeStore.setErrorString("");
                        }
                        if (volInfo.isCorrupted()) {
                            volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
                            String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
                            volumeStore.setErrorString(msg);
                            s_logger.info(msg);
                            if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
                                s_logger.info("Volume Sync found " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + " as corrupted, marking it as failed");
                                _volumeStoreDao.update(volumeStore.getId(), volumeStore);
                                // mark volume as failed, so that storage GC will clean it up
                                VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
                                volObj.processEvent(Event.OperationFailed);
                            } else if (volumeStore.getDownloadUrl() == null) {
                                msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: " + volumeStore.getDataStoreId();
                                s_logger.warn(msg);
                            } else {
                                s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
                                _volumeStoreDao.remove(volumeStore.getId());
                                toBeDownloaded.add(volumeStore);
                            }
                        } else {
                            // Put them in right status
                            volumeStore.setDownloadPercent(100);
                            volumeStore.setDownloadState(Status.DOWNLOADED);
                            volumeStore.setState(ObjectInDataStoreStateMachine.State.Ready);
                            volumeStore.setInstallPath(volInfo.getInstallPath());
                            volumeStore.setSize(volInfo.getSize());
                            volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
                            volumeStore.setLastUpdated(new Date());
                            _volumeStoreDao.update(volumeStore.getId(), volumeStore);
                            if (volume.getSize() == 0) {
                                // Set volume size in volumes table
                                volume.setSize(volInfo.getSize());
                                volDao.update(volumeStore.getVolumeId(), volume);
                            }
                            if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
                                VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
                                volObj.processEvent(Event.OperationSuccessed);
                            }
                            if (volInfo.getSize() > 0) {
                                try {
                                    _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize());
                                } catch (ResourceAllocationException e) {
                                    s_logger.warn(e.getMessage());
                                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
                                } finally {
                                    _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
                                }
                            }
                        }
                        continue;
                    } else if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
                        // failed uploads through SSVM
                        s_logger.info("Volume Sync did not find " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + ", marking it as failed");
                        toBeDownloaded.remove(volumeStore);
                        volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
                        String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
                        volumeStore.setErrorString(msg);
                        _volumeStoreDao.update(volumeStore.getId(), volumeStore);
                        // mark volume as failed, so that storage GC will clean it up
                        VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
                        volObj.processEvent(Event.OperationFailed);
                        continue;
                    }
                    // Volume is not on secondary but we should download.
                    if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
                        s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
                    }
                }
                // Download volumes which haven't been downloaded yet.
                if (toBeDownloaded.size() > 0) {
                    for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
                        if (volumeHost.getDownloadUrl() == null) {
                            // If url is null, skip downloading
                            s_logger.info("Skip downloading volume " + volumeHost.getVolumeId() + " since no download url is specified.");
                            continue;
                        }
                        // means that this is a duplicate entry from migration of previous NFS to staging.
                        if (store.getScope().getScopeType() == ScopeType.REGION) {
                            if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED && volumeHost.getInstallPath() == null) {
                                s_logger.info("Skip sync volume for migration of previous NFS to object store");
                                continue;
                            }
                        }
                        s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
                        // reset volume status back to Allocated
                        VolumeObject vol = (VolumeObject) volFactory.getVolume(volumeHost.getVolumeId());
                        // reset back volume status
                        vol.processEvent(Event.OperationFailed);
                        // remove leftover volume_store_ref entry since re-download will create it again
                        _volumeStoreDao.remove(volumeHost.getId());
                        // get an updated volumeVO
                        vol = (VolumeObject) volFactory.getVolume(volumeHost.getVolumeId());
                        RegisterVolumePayload payload = new RegisterVolumePayload(volumeHost.getDownloadUrl(), volumeHost.getChecksum(), vol.getFormat().toString());
                        vol.addPayload(payload);
                        createVolumeAsync(vol, store);
                    }
                }
                // Delete volumes which are not present on DB.
                for (Map.Entry<Long, TemplateProp> entry : volumeInfos.entrySet()) {
                    Long uniqueName = entry.getKey();
                    TemplateProp tInfo = entry.getValue();
                    // we cannot directly call expungeVolumeAsync here to reuse delete logic since in this case db does not have this volume at all.
                    VolumeObjectTO tmplTO = new VolumeObjectTO();
                    tmplTO.setDataStore(store.getTO());
                    tmplTO.setPath(tInfo.getInstallPath());
                    tmplTO.setId(tInfo.getId());
                    DeleteCommand dtCommand = new DeleteCommand(tmplTO);
                    EndPoint ep = _epSelector.select(store);
                    Answer answer = null;
                    if (ep == null) {
                        String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
                        s_logger.error(errMsg);
                        answer = new Answer(dtCommand, false, errMsg);
                    } else {
                        answer = ep.sendMessage(dtCommand);
                    }
                    if (answer == null || !answer.getResult()) {
                        s_logger.info("Failed to deleted volume at store: " + store.getName());
                    } else {
                        String description = "Deleted volume " + tInfo.getTemplateName() + " on secondary storage " + storeId;
                        s_logger.info(description);
                    }
                }
            } finally {
                syncLock.unlock();
            }
        } else {
            s_logger.info("Couldn't get global lock on " + lockString + ", another thread may be doing volume sync on data store " + storeId + " now.");
        }
    } finally {
        syncLock.releaseRef();
    }
}
Also used : TemplateProp(com.cloud.storage.template.TemplateProp) ArrayList(java.util.ArrayList) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) RemoteHostEndPoint(org.apache.cloudstack.storage.RemoteHostEndPoint) RegisterVolumePayload(com.cloud.storage.RegisterVolumePayload) Date(java.util.Date) GlobalLock(com.cloud.utils.db.GlobalLock) DeleteCommand(org.apache.cloudstack.storage.command.DeleteCommand) Answer(com.cloud.agent.api.Answer) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) ListVolumeAnswer(com.cloud.agent.api.storage.ListVolumeAnswer) VolumeVO(com.cloud.storage.VolumeVO) VolumeDataStoreVO(org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with VolumeObjectTO

use of org.apache.cloudstack.storage.to.VolumeObjectTO in project cloudstack by apache.

the class LibvirtDeleteVMSnapshotCommandWrapper method execute.

@Override
public Answer execute(final DeleteVMSnapshotCommand cmd, final LibvirtComputingResource libvirtComputingResource) {
    String vmName = cmd.getVmName();
    final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
    Domain dm = null;
    DomainSnapshot snapshot = null;
    try {
        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
        Connect conn = libvirtUtilitiesHelper.getConnection();
        dm = libvirtComputingResource.getDomain(conn, vmName);
        snapshot = dm.snapshotLookupByName(cmd.getTarget().getSnapshotName());
        // only remove this snapshot, not children
        snapshot.delete(0);
        return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());
    } catch (LibvirtException e) {
        String msg = " Delete VM snapshot failed due to " + e.toString();
        if (dm == null) {
            s_logger.debug("Can not find running vm: " + vmName + ", now we are trying to delete the vm snapshot using qemu-img if the format of root volume is QCOW2");
            VolumeObjectTO rootVolume = null;
            for (VolumeObjectTO volume : cmd.getVolumeTOs()) {
                if (volume.getVolumeType() == Volume.Type.ROOT) {
                    rootVolume = volume;
                    break;
                }
            }
            if (rootVolume != null && ImageFormat.QCOW2.equals(rootVolume.getFormat())) {
                PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) rootVolume.getDataStore();
                KVMPhysicalDisk rootDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), rootVolume.getPath());
                String qemu_img_snapshot = Script.runSimpleBashScript("qemu-img snapshot -l " + rootDisk.getPath() + " | tail -n +3 | awk -F ' ' '{print $2}' | grep ^" + cmd.getTarget().getSnapshotName() + "$");
                if (qemu_img_snapshot == null) {
                    s_logger.info("Cannot find snapshot " + cmd.getTarget().getSnapshotName() + " in file " + rootDisk.getPath() + ", return true");
                    return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());
                }
                int result = Script.runSimpleBashScriptForExitValue("qemu-img snapshot -d " + cmd.getTarget().getSnapshotName() + " " + rootDisk.getPath());
                if (result != 0) {
                    return new DeleteVMSnapshotAnswer(cmd, false, "Delete VM Snapshot Failed due to can not remove snapshot from image file " + rootDisk.getPath() + " : " + result);
                } else {
                    return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());
                }
            }
        } else if (snapshot == null) {
            s_logger.debug("Can not find vm snapshot " + cmd.getTarget().getSnapshotName() + " on vm: " + vmName + ", return true");
            return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());
        }
        s_logger.warn(msg, e);
        return new DeleteVMSnapshotAnswer(cmd, false, msg);
    } finally {
        if (dm != null) {
            try {
                dm.free();
            } catch (LibvirtException l) {
                s_logger.trace("Ignoring libvirt error.", l);
            }
            ;
        }
    }
}
Also used : KVMStoragePoolManager(com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager) LibvirtException(org.libvirt.LibvirtException) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) KVMPhysicalDisk(com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk) Connect(org.libvirt.Connect) DomainSnapshot(org.libvirt.DomainSnapshot) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) DeleteVMSnapshotAnswer(com.cloud.agent.api.DeleteVMSnapshotAnswer) Domain(org.libvirt.Domain)

Example 3 with VolumeObjectTO

use of org.apache.cloudstack.storage.to.VolumeObjectTO in project cloudstack by apache.

the class OvmResourceBase method createVbds.

protected void createVbds(OvmVm.Details vm, VirtualMachineTO spec) throws URISyntaxException {
    for (DiskTO volume : spec.getDisks()) {
        if (volume.getType() == Volume.Type.ROOT) {
            VolumeObjectTO vol = (VolumeObjectTO) volume.getData();
            OvmDisk.Details root = new OvmDisk.Details();
            root.path = vol.getPath();
            root.type = OvmDisk.WRITE;
            root.isIso = false;
            vm.rootDisk = root;
        } else if (volume.getType() == Volume.Type.ISO) {
            DataTO isoTO = volume.getData();
            if (isoTO.getPath() != null) {
                TemplateObjectTO template = (TemplateObjectTO) isoTO;
                DataStoreTO store = template.getDataStore();
                if (!(store instanceof NfsTO)) {
                    throw new CloudRuntimeException("unsupported protocol");
                }
                NfsTO nfsStore = (NfsTO) store;
                String isoPath = nfsStore.getUrl() + File.separator + template.getPath();
                OvmDisk.Details iso = new OvmDisk.Details();
                URI path = new URI(isoPath);
                iso.path = path.getHost() + ":" + path.getPath();
                iso.type = OvmDisk.READ;
                iso.isIso = true;
                vm.disks.add(iso);
            }
        } else if (volume.getType() == Volume.Type.DATADISK) {
            OvmDisk.Details data = new OvmDisk.Details();
            data.path = volume.getData().getPath();
            data.type = OvmDisk.SHAREDWRITE;
            data.isIso = false;
            vm.disks.add(data);
        } else {
            throw new CloudRuntimeException("Unknow volume type: " + volume.getType());
        }
    }
}
Also used : DataStoreTO(com.cloud.agent.api.to.DataStoreTO) DataTO(com.cloud.agent.api.to.DataTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) OvmDisk(com.cloud.ovm.object.OvmDisk) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) NfsTO(com.cloud.agent.api.to.NfsTO) URI(java.net.URI) DiskTO(com.cloud.agent.api.to.DiskTO)

Example 4 with VolumeObjectTO

use of org.apache.cloudstack.storage.to.VolumeObjectTO in project cloudstack by apache.

the class VmwareStorageMotionStrategy method updateVolumesAfterMigration.

private void updateVolumesAfterMigration(Map<VolumeInfo, DataStore> volumeToPool, List<VolumeObjectTO> volumeTos) {
    for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
        boolean updated = false;
        VolumeInfo volume = entry.getKey();
        StoragePool pool = (StoragePool) entry.getValue();
        for (VolumeObjectTO volumeTo : volumeTos) {
            if (volume.getId() == volumeTo.getId()) {
                VolumeVO volumeVO = volDao.findById(volume.getId());
                Long oldPoolId = volumeVO.getPoolId();
                volumeVO.setPath(volumeTo.getPath());
                if (volumeTo.getChainInfo() != null) {
                    volumeVO.setChainInfo(volumeTo.getChainInfo());
                }
                volumeVO.setLastPoolId(oldPoolId);
                volumeVO.setFolder(pool.getPath());
                volumeVO.setPodId(pool.getPodId());
                volumeVO.setPoolId(pool.getId());
                volDao.update(volume.getId(), volumeVO);
                updated = true;
                break;
            }
        }
        if (!updated) {
            s_logger.error("Volume path wasn't updated for volume " + volume + " after it was migrated.");
        }
    }
}
Also used : StoragePool(com.cloud.storage.StoragePool) VolumeVO(com.cloud.storage.VolumeVO) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) Map(java.util.Map)

Example 5 with VolumeObjectTO

use of org.apache.cloudstack.storage.to.VolumeObjectTO in project cloudstack by apache.

the class VmwareStorageProcessor method createTemplateFromVolume.

@Override
public Answer createTemplateFromVolume(CopyCommand cmd) {
    VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO();
    TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO();
    DataStoreTO imageStore = template.getDataStore();
    if (!(imageStore instanceof NfsTO)) {
        return new CopyCmdAnswer("unsupported protocol");
    }
    NfsTO nfsImageStore = (NfsTO) imageStore;
    String secondaryStoragePoolURL = nfsImageStore.getUrl();
    String volumePath = volume.getPath();
    String details = null;
    VmwareContext context = hostService.getServiceContext(cmd);
    try {
        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(volume.getVmName());
        if (vmMo == null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter");
            }
            vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName());
            if (vmMo == null) {
                // This means either the volume is on a zone wide storage pool or VM is deleted by external entity.
                // Look for the VM in the datacenter.
                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
                DatacenterMO dcMo = new DatacenterMO(context, dcMor);
                vmMo = dcMo.findVm(volume.getVmName());
            }
            if (vmMo == null) {
                String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName();
                s_logger.error(msg);
                throw new Exception(msg);
            }
        }
        Ternary<String, Long, Long> result = createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath, hostService.getWorkerName(context, cmd, 0), _nfsVersion);
        TemplateObjectTO newTemplate = new TemplateObjectTO();
        newTemplate.setPath(result.first());
        newTemplate.setFormat(ImageFormat.OVA);
        newTemplate.setSize(result.third());
        newTemplate.setPhysicalSize(result.second());
        return new CopyCmdAnswer(newTemplate);
    } catch (Throwable e) {
        if (e instanceof RemoteException) {
            hostService.invalidateServiceContext(context);
        }
        s_logger.error("Unexpecpted exception ", e);
        details = "create template from volume exception: " + VmwareHelper.getExceptionMessage(e);
        return new CopyCmdAnswer(details);
    }
}
Also used : PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) VirtualMachineMO(com.cloud.hypervisor.vmware.mo.VirtualMachineMO) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) NfsTO(com.cloud.agent.api.to.NfsTO) RemoteException(java.rmi.RemoteException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) RemoteException(java.rmi.RemoteException) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference) DatacenterMO(com.cloud.hypervisor.vmware.mo.DatacenterMO)

Aggregations

VolumeObjectTO (org.apache.cloudstack.storage.to.VolumeObjectTO)108 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)59 CopyCmdAnswer (org.apache.cloudstack.storage.command.CopyCmdAnswer)45 DataStoreTO (com.cloud.agent.api.to.DataStoreTO)36 PrimaryDataStoreTO (org.apache.cloudstack.storage.to.PrimaryDataStoreTO)36 DataTO (com.cloud.agent.api.to.DataTO)31 NfsTO (com.cloud.agent.api.to.NfsTO)31 InternalErrorException (com.cloud.exception.InternalErrorException)27 TemplateObjectTO (org.apache.cloudstack.storage.to.TemplateObjectTO)20 Connection (com.xensource.xenapi.Connection)19 VDI (com.xensource.xenapi.VDI)17 IOException (java.io.IOException)17 Answer (com.cloud.agent.api.Answer)16 DiskTO (com.cloud.agent.api.to.DiskTO)16 ManagedObjectReference (com.vmware.vim25.ManagedObjectReference)16 RemoteException (java.rmi.RemoteException)16 ArrayList (java.util.ArrayList)16 SnapshotObjectTO (org.apache.cloudstack.storage.to.SnapshotObjectTO)16 VmwareHypervisorHost (com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost)14 UnsupportedEncodingException (java.io.UnsupportedEncodingException)14