This is an automated email from the ASF dual-hosted git repository. harikrishna pushed a commit to branch LiveStoragMigrationScaleIOMain in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit de1d6c258676d84b1ba345c61cde552d5c0f0a1a Author: Harikrishna Patnala <harikrishna.patn...@gmail.com> AuthorDate: Mon Mar 6 13:12:19 2023 +0530 recent changes --- .../LibvirtMigrateVolumeCommandWrapper.java | 116 +++++++++++++-------- .../driver/ScaleIOPrimaryDataStoreDriver.java | 23 ++-- 2 files changed, 84 insertions(+), 55 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java index 8ad52664751..6ff437cd44c 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java @@ -48,6 +48,7 @@ import org.libvirt.Connect; import org.libvirt.Domain; import org.libvirt.DomainInfo; import org.libvirt.TypedParameter; +import org.libvirt.TypedUlongParameter; import org.libvirt.LibvirtException; import org.libvirt.event.BlockJobListener; import org.libvirt.event.BlockJobStatus; @@ -59,8 +60,6 @@ public final class LibvirtMigrateVolumeCommandWrapper extends CommandWrapper<Mig @Override public Answer execute(final MigrateVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { - LOGGER.info("I'm here HARIIIII"); - VolumeObjectTO srcVolumeObjectTO = (VolumeObjectTO)command.getSrcData(); PrimaryDataStoreTO srcPrimaryDataStore = (PrimaryDataStoreTO)srcVolumeObjectTO.getDataStore(); @@ -75,76 +74,82 @@ public final class LibvirtMigrateVolumeCommandWrapper extends CommandWrapper<Mig } private MigrateVolumeAnswer migrateVolumeInternal (final MigrateVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { - VolumeObjectTO srcVolumeObjectTO = (VolumeObjectTO)command.getSrcData(); - PrimaryDataStoreTO srcPrimaryDataStore = (PrimaryDataStoreTO)srcVolumeObjectTO.getDataStore(); - final String vmName = srcVolumeObjectTO.getVmName(); - LOGGER.info("HARI VM name: "+ vmName); - - VolumeObjectTO destVolumeObjectTO = (VolumeObjectTO)command.getDestData(); - PrimaryDataStoreTO destPrimaryDataStore = (PrimaryDataStoreTO)destVolumeObjectTO.getDataStore(); + // Source Details + VolumeObjectTO srcVolumeObjectTO = (VolumeObjectTO)command.getSrcData(); String srcPath = srcVolumeObjectTO.getPath(); - String destPath = destVolumeObjectTO.getPath(); + final String srcVolumeId = ScaleIOUtil.getVolumePath(srcVolumeObjectTO.getPath()); + final String vmName = srcVolumeObjectTO.getVmName(); + Map<String, String> srcDetails = command.getSrcDetails(); + final String srcSystemId = srcDetails.get(ScaleIOGatewayClient.STORAGE_POOL_SYSTEM_ID); - Map<String, String> destDetails = command.getDestDetails(); + final String diskFileName = ScaleIOUtil.DISK_NAME_PREFIX + srcSystemId + "-" + srcVolumeId; + final String srcFilePath = ScaleIOUtil.DISK_PATH + File.separator + diskFileName; - final String srcVolumeId = ScaleIOUtil.getVolumePath(srcVolumeObjectTO.getPath()); LOGGER.info("HARI Source volume ID: "+ srcVolumeId); + LOGGER.info("HARI source volume PATH: "+ srcFilePath); + LOGGER.info("HARI source system ID: "+ srcSystemId); + // Destination Details + VolumeObjectTO destVolumeObjectTO = (VolumeObjectTO)command.getDestData(); + String destPath = destVolumeObjectTO.getPath(); final String destVolumeId = ScaleIOUtil.getVolumePath(destVolumeObjectTO.getPath()); - LOGGER.info("HARI destination volume ID: "+ destVolumeId); - + Map<String, String> destDetails = command.getDestDetails(); final String destSystemId = destDetails.get(ScaleIOGatewayClient.STORAGE_POOL_SYSTEM_ID); - LOGGER.info("HARI destination system ID: "+ destSystemId); - final String destDiskFileName = ScaleIOUtil.DISK_NAME_PREFIX + destSystemId + "-" + destVolumeId; final String diskFilePath = ScaleIOUtil.DISK_PATH + File.separator + destDiskFileName; + LOGGER.info("HARI destination volume ID: "+ destVolumeId); + LOGGER.info("HARI destination system ID: "+ destSystemId); + Domain dm = null; try { final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); Connect conn = libvirtUtilitiesHelper.getConnection(); dm = libvirtComputingResource.getDomain(conn, vmName); - if (dm == null) { - return new MigrateVolumeAnswer(command, false, - "Migrate volume failed due to can not find vm: " + vmName, null); + return new MigrateVolumeAnswer(command, false, "Migrate volume failed due to can not find vm: " + vmName, null); } DomainInfo.DomainState domainState = dm.getInfo().state ; if (domainState != DomainInfo.DomainState.VIR_DOMAIN_RUNNING) { - return new MigrateVolumeAnswer(command, false, - "Migrate volume failed due to VM is not running: " + vmName + " with domainState = " + domainState, null); + return new MigrateVolumeAnswer(command, false, "Migrate volume failed due to VM is not running: " + vmName + " with domainState = " + domainState, null); } - final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); - final String domXml = dm.getXMLDesc(0); - parser.parseDomainXML(domXml); - LOGGER.info(String.format("VM [%s] with XML configuration [%s] will be migrated to host.", vmName, domXml)); - - List<LibvirtVMDef.DiskDef> disks = parser.getDisks(); - LibvirtVMDef.DiskDef diskdef = null; - for (final LibvirtVMDef.DiskDef disk : disks) { - final String file = disk.getDiskPath(); - LOGGER.info("HARIIII : " + file); - if (file != null && file.contains(srcVolumeId)) { - diskdef = disk; - break; - } - } - if (diskdef == null) { - throw new InternalErrorException("disk: " + srcPath + " is not attached before"); - } - diskdef.setDiskPath(diskFilePath); - LOGGER.info("HARIIII Destination xml : " + diskdef.toString()); - dm.blockCopy(srcPath, diskdef.toString(), new TypedParameter[]{}, 0); + LibvirtVMDef.DiskDef diskdef = generateDestinationDiskDefinition(dm, srcVolumeId, srcPath, diskFilePath); + + TypedUlongParameter parameter = new TypedUlongParameter("bandwidth", 0); + TypedParameter[] parameters = new TypedParameter[1]; + parameters[0] = parameter; + LOGGER.info("Krishna source disk label: " + diskdef.getDiskLabel()); + + Domain finalDm = dm; + final Boolean[] copyStatus = {true}; + dm.blockCopy(diskdef.getDiskLabel(), diskdef.toString(), parameters, Domain.BlockCopyFlags.REUSE_EXT); BlockJobListener listener = new BlockJobListener() { @Override public void onEvent(Domain domain, String diskPath, BlockJobType type, BlockJobStatus status) { - + if (type == BlockJobType.COPY && status == BlockJobStatus.READY) { + try { + finalDm.blockJobAbort(diskFilePath, 0); + copyStatus[0] = false; + } catch (LibvirtException e) { + throw new RuntimeException(e); + } + } } }; + dm.addBlockJobListener(listener); + while (copyStatus[0]) { + LOGGER.info("Waiting for the block copy to complete"); + } + + if (copyStatus[0]) { + String msg = "Migrate volume failed due to timeout"; + LOGGER.warn(msg); + return new MigrateVolumeAnswer(command, false, msg, null); + } return new MigrateVolumeAnswer(command, true, null, destPath); } catch (Exception e) { @@ -161,6 +166,31 @@ public final class LibvirtMigrateVolumeCommandWrapper extends CommandWrapper<Mig } } } + + private LibvirtVMDef.DiskDef generateDestinationDiskDefinition(Domain dm, String srcVolumeId, String srcPath, String diskFilePath) throws InternalErrorException, LibvirtException { + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + final String domXml = dm.getXMLDesc(0); + parser.parseDomainXML(domXml); + + List<LibvirtVMDef.DiskDef> disks = parser.getDisks(); + LibvirtVMDef.DiskDef diskdef = null; + for (final LibvirtVMDef.DiskDef disk : disks) { + final String file = disk.getDiskPath(); + LOGGER.info("HARIIII disk: " + file); + if (file != null && file.contains(srcVolumeId)) { + diskdef = disk; + break; + } + } + if (diskdef == null) { + throw new InternalErrorException("disk: " + srcPath + " is not attached before"); + } + diskdef.setDiskPath(diskFilePath); + LOGGER.info("HARIIII Destination xml : " + diskdef.toString()); + + return diskdef; + } + private MigrateVolumeAnswer migrateRegularVolume(final MigrateVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { KVMStoragePoolManager storagePoolManager = libvirtComputingResource.getStoragePoolMgr(); diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/driver/ScaleIOPrimaryDataStoreDriver.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/driver/ScaleIOPrimaryDataStoreDriver.java index 81abff9ff38..6c3dd0f1b08 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/driver/ScaleIOPrimaryDataStoreDriver.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/driver/ScaleIOPrimaryDataStoreDriver.java @@ -19,7 +19,6 @@ package org.apache.cloudstack.storage.datastore.driver; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import javax.inject.Inject; @@ -773,18 +772,17 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver { final String srcVolumeId = ScaleIOUtil.getVolumePath(srcVolumePath); final StoragePoolVO destStoragePool = storagePoolDao.findById(destPoolId); final String destStoragePoolId = destStoragePool.getPath(); - //CreateObjectAnswer createAnswer = createVolume((VolumeInfo) destData, destStore.getId()); - //String destVolumePath = createAnswer.getData().getPath(); - final String destVolumeId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16); - final String destScaleIOVolumeName = String.format("%s-%s-%s-%s", ScaleIOUtil.VOLUME_PREFIX, srcData.getId(), - srcData.getUuid().split("-")[0].substring(4), ManagementServerImpl.customCsIdentifier.value()); - String destVolumePath = String.format("%s:%s", destVolumeId, destScaleIOVolumeName); + CreateObjectAnswer createAnswer = createVolume((VolumeInfo) destData, destStore.getId()); + String destVolumePath = createAnswer.getData().getPath(); + //final String destVolumeId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16); + //final String destScaleIOVolumeName = String.format("%s-%s-%s-%s", ScaleIOUtil.VOLUME_PREFIX, srcData.getId(), srcData.getUuid().split("-")[0].substring(4), ManagementServerImpl.customCsIdentifier.value()); + //String destVolumePath = String.format("%s:%s", destVolumeId, destScaleIOVolumeName); VolumeObjectTO destVolTO = (VolumeObjectTO) destData.getTO(); destVolTO.setPath(destVolumePath); - Map<String, String> srcDetails = getVolumeDetails((VolumeInfo) srcData); - Map<String, String> destDetails = getVolumeDetails((VolumeInfo) destData); + Map<String, String> srcDetails = getVolumeDetails((VolumeInfo) srcData, srcStore); + Map<String, String> destDetails = getVolumeDetails((VolumeInfo) destData, destStore); String value = configDao.getValue(Config.MigrateWait.key()); int waitInterval = NumbersUtil.parseInt(value, Integer.parseInt(Config.MigrateWait.getDefaultValue())); @@ -804,6 +802,7 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver { throw new CloudRuntimeException("Found no hosts to run resize command on"); } EndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(host); + grantAccess(destData, ep, destData.getDataStore()); answer = ep.sendMessage(migrateVolumeCommand); boolean migrateStatus = answer.getResult(); @@ -878,8 +877,8 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver { return answer; } - private Map<String, String> getVolumeDetails(VolumeInfo volumeInfo) { - long storagePoolId = volumeInfo.getPoolId(); + private Map<String, String> getVolumeDetails(VolumeInfo volumeInfo, DataStore dataStore) { + long storagePoolId = dataStore.getId(); StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId); if (!storagePoolVO.isManaged()) { @@ -899,7 +898,7 @@ public class ScaleIOPrimaryDataStoreDriver implements PrimaryDataStoreDriver { volumeDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeVO.getSize())); volumeDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getVolumeProperty(volumeInfo.getId(), DiskTO.SCSI_NAA_DEVICE_ID)); - ChapInfo chapInfo = volumeService.getChapInfo(volumeInfo, volumeInfo.getDataStore()); + ChapInfo chapInfo = volumeService.getChapInfo(volumeInfo, dataStore); if (chapInfo != null) { volumeDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());