This is an automated email from the ASF dual-hosted git repository. Pearl1594 pushed a commit to branch minor-improvements-clvm in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit a7b9a414fa18e03d799ff7bc0991a5f2c2aee500 Author: Pearl Dsilva <[email protected]> AuthorDate: Mon Jun 22 15:39:36 2026 -0400 CLVM: Fix volume mapping and disk path matching for storage migration --- .../com/cloud/vm/VirtualMachineManagerImpl.java | 3 ++- .../storage/motion/AncientDataMotionStrategy.java | 21 +++++++++++++++++++++ .../storage/volume/VolumeServiceImpl.java | 6 ++++++ .../kvm/resource/LibvirtComputingResource.java | 2 +- .../CloudStackPrimaryDataStoreDriverImpl.java | 12 +++--------- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index c27240823b1..d74ed7dcd6c 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -3543,7 +3543,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected boolean shouldMapVolume(VirtualMachineProfile profile, StoragePoolVO currentPool) { boolean isManaged = currentPool.isManaged(); boolean isNotKvm = HypervisorType.KVM != profile.getHypervisorType(); - return isNotKvm || isManaged; + boolean isClvm = ClvmPoolManager.isClvmPoolType(currentPool.getPoolType()); + return isNotKvm || isManaged || isClvm; } /** diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 95362f44b13..9e54d07e993 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -408,6 +408,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { answer = new Answer(cmd, false, errMsg); } else { answer = ep.sendMessage(cmd); + if (answer != null && answer.getResult()) { + setClvmLockHostIdIfApplicable(destData, ep); + } } return answer; } @@ -463,6 +466,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { imageStore.delete(objOnImageStore); return answer; } + setClvmLockHostIdIfApplicable(destData, ep); } catch (Exception e) { if (imageStore.exists(objOnImageStore)) { objOnImageStore.processEvent(Event.OperationFailed); @@ -486,6 +490,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { answer = new Answer(cmd, false, errMsg); } else { answer = ep.sendMessage(cmd); + if (answer != null && answer.getResult()) { + setClvmLockHostIdIfApplicable(destData, ep); + } } // delete volume on cache store if (cacheData != null) { @@ -495,6 +502,17 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } } + private void setClvmLockHostIdIfApplicable(DataObject destData, EndPoint ep) { + if (ep == null || !(destData instanceof VolumeInfo)) { + return; + } + VolumeInfo destVolume = (VolumeInfo) destData; + if (ClvmPoolManager.isClvmPoolType(destVolume.getStoragePoolType())) { + clvmPoolManager.setClvmLockHostId(destVolume.getId(), ep.getId()); + logger.debug("Set CLVM lock host {} for migrated volume {}", ep.getId(), destVolume.getUuid()); + } + } + private boolean canBypassSecondaryStorage(DataObject srcData, DataObject destData) { if (srcData instanceof VolumeInfo) { if (((VolumeInfo)srcData).isDirectDownload()) { @@ -613,6 +631,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { if (destPool.getPoolType() == StoragePoolType.CLVM) { volumeVo.setFormat(ImageFormat.RAW); } + if (ClvmPoolManager.isClvmPoolType(destPool.getPoolType())) { + clvmPoolManager.setClvmLockHostId(volume.getId(), ep.getId()); + } // For SMB, pool credentials are also stored in the uri query string. We trim the query string // part here to make sure the credentials do not get stored in the db unencrypted. String folder = destPool.getPath(); diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 6fe4c2708c5..61ca1b7a2e3 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -3096,6 +3096,12 @@ public class VolumeServiceImpl implements VolumeService { } if (volumePoolId == null || !volumePoolId.equals(vmPoolId)) { + Long volumeLockHostId = findVolumeLockHost(volumeToAttach); + if (volumeLockHostId != null && vmHostId != null && !volumeLockHostId.equals(vmHostId)) { + logger.info("CLVM cross-pool lock transfer required: Volume {} on pool {} lock is on host {} but VM is on host {}", + volumeToAttach.getUuid(), volumePoolId, volumeLockHostId, vmHostId); + return true; + } return false; } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 4a93b1bce4a..4f32762b2fb 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -7022,7 +7022,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv continue; } VolumeObjectTO volumeTO = (VolumeObjectTO) diskTO.getData(); - if (!diskPath.equals(volumeTO.getPath()) && !diskPath.equals(diskTO.getPath())) { + if (!diskPath.substring(diskPath.lastIndexOf(File.separator) + 1).equals(volumeTO.getPath())) { continue; } DataStoreTO dataStore = volumeTO.getDataStore(); diff --git a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 9174aaa3869..0d8b939822b 100644 --- a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -437,16 +437,10 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri try { EndPoint ep = null; VolumeInfo volumeInfo = volFactory.getVolume(snapshot.getVolumeId(), DataStoreRole.Primary); - - StoragePoolVO storagePool = primaryStoreDao.findById(volumeInfo.getPoolId()); - if (storagePool != null && storagePool.getPoolType() == StoragePoolType.CLVM) { - ep = epSelector.select(volumeInfo); + if (snapshotOnPrimaryStore != null) { + ep = epSelector.select(snapshotOnPrimaryStore); } else { - if (snapshotOnPrimaryStore != null) { - ep = epSelector.select(snapshotOnPrimaryStore); - } else { - ep = epSelector.select(volumeInfo); - } + ep = epSelector.select(volumeInfo); } if ( ep == null ){
