From 2d2f74078ffaf41a2fb2f8c45e5e20f3f3695870 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:48:52 +0530 Subject: [PATCH] Support local storage and shared mount point --- .../LibvirtStartBackupCommandWrapper.java | 1 - .../backup/KVMBackupExportServiceImpl.java | 61 ++++++++++++++----- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartBackupCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartBackupCommandWrapper.java index 4ed39f1ae89..2e7c8c5ae98 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartBackupCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartBackupCommandWrapper.java @@ -171,7 +171,6 @@ public class LibvirtStartBackupCommandWrapper extends CommandWrapper hosts = null; - if (storagePoolVO.getScope().equals(ScopeType.CLUSTER)) { - hosts = hostDao.findByClusterId(storagePoolVO.getClusterId()); - - } else if (storagePoolVO.getScope().equals(ScopeType.ZONE)) { - hosts = hostDao.findByDataCenterId(storagePoolVO.getDataCenterId()); + private HostVO getRandomHostFromStoragePool(StoragePoolVO storagePool) { + List hosts; + switch (storagePool.getScope()) { + case CLUSTER: + hosts = hostDao.findByClusterId(storagePool.getClusterId()); + Collections.shuffle(hosts); + return hosts.get(0); + case ZONE: + hosts = hostDao.findByDataCenterId(storagePool.getDataCenterId()); + Collections.shuffle(hosts); + return hosts.get(0); + case HOST: + List storagePoolHostVOs = storagePoolHostDao.listByPoolId(storagePool.getId()); + Collections.shuffle(storagePoolHostVOs); + return hostDao.findById(storagePoolHostVOs.get(0).getHostId()); + default: + throw new CloudRuntimeException("Unsupported storage pool scope: " + storagePool.getScope()); } - return hosts.get(0); } private void startNBDServer(String transferId, String direction, Long hostId, String exportName, String volumePath, String checkpointId) { @@ -396,12 +411,24 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup } } + private String getVolumePathPrefix(StoragePoolVO storagePool) { + if (ScopeType.HOST.equals(storagePool.getScope())) { + return storagePool.getPath(); + } + switch (storagePool.getPoolType()) { + case NetworkFilesystem: + return String.format("/mnt/%s", storagePool.getUuid()); + case SharedMountPoint: + return storagePool.getPath(); + default: + throw new CloudRuntimeException("Unsupported storage pool type for file based image transfer: " + storagePool.getPoolType()); + } + } + private String getVolumePathForFileBasedBackend(Volume volume) { - Long poolId = volume.getPoolId(); - StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(poolId); - // todo: This only works with file based storage (not ceph, linbit) - String volumePath = String.format("/mnt/%s/%s", storagePoolVO.getUuid(), volume.getPath()); - return volumePath; + StoragePoolVO storagePool = primaryDataStoreDao.findById(volume.getPoolId()); + String volumePathPrefix = getVolumePathPrefix(storagePool); + return volumePathPrefix + "/" + volume.getPath(); } private ImageTransferVO createUploadImageTransfer(VolumeVO volume, ImageTransfer.Backend backend) { @@ -409,8 +436,12 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup String transferId = UUID.randomUUID().toString(); Long poolId = volume.getPoolId(); - StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(poolId); - Host host = getFirstHostFromStoragePool(storagePoolVO); + StoragePoolVO storagePool = poolId == null ? null : primaryDataStoreDao.findById(poolId); + if (storagePool == null) { + throw new CloudRuntimeException("Storage pool cannot be determined for volume: " + volume.getUuid()); + } + + Host host = getRandomHostFromStoragePool(storagePool); String volumePath = getVolumePathForFileBasedBackend(volume); ImageTransferVO imageTransfer;