This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.19 by this push:
     new 3f5a77ef580 Linstor: Fix migrate primary storage (#9528)
3f5a77ef580 is described below

commit 3f5a77ef5802871d24777ef8a50f46b952e200a6
Author: Rene Peinthor <rene.peint...@linbit.com>
AuthorDate: Mon Sep 9 10:01:41 2024 +0200

    Linstor: Fix migrate primary storage (#9528)
---
 .../hypervisor/kvm/storage/KVMPhysicalDisk.java    | 27 ++++++++++++++--
 .../kvm/storage/KVMStorageProcessor.java           |  5 +++
 .../kvm/storage/LibvirtStorageAdaptor.java         |  5 ++-
 .../kvm/storage/LinstorStorageAdaptor.java         |  9 ++++++
 .../driver/LinstorPrimaryDataStoreDriverImpl.java  | 37 +++++-----------------
 .../storage/datastore/util/LinstorUtil.java        | 24 ++++++++++++++
 .../snapshot/LinstorVMSnapshotStrategy.java        |  4 +--
 7 files changed, 76 insertions(+), 35 deletions(-)

diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
index c9abf399530..9d9a6415e27 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
@@ -18,6 +18,7 @@ package com.cloud.hypervisor.kvm.storage;
 
 import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
 import org.apache.cloudstack.utils.qemu.QemuObject;
+import 
org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.ArrayList;
@@ -25,8 +26,10 @@ import java.util.List;
 
 public class KVMPhysicalDisk {
     private String path;
-    private String name;
-    private KVMStoragePool pool;
+    private final String name;
+    private final KVMStoragePool pool;
+    private String dispName;
+    private String vmName;
     private boolean useAsTemplate;
 
     public static String RBDStringBuilder(String monHost, int monPort, String 
authUserName, String authSecret, String image) {
@@ -81,7 +84,9 @@ public class KVMPhysicalDisk {
 
     @Override
     public String toString() {
-        return "KVMPhysicalDisk [path=" + path + ", name=" + name + ", pool=" 
+ pool + ", format=" + format + ", size=" + size + ", virtualSize=" + 
virtualSize + "]";
+        return String.format("KVMPhysicalDisk %s",
+                ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
+                        this, "path", "name", "pool", "format", "size", 
"virtualSize", "dispName", "vmName"));
     }
 
     public void setFormat(PhysicalDiskFormat format) {
@@ -135,4 +140,20 @@ public class KVMPhysicalDisk {
     public void setUseAsTemplate() { this.useAsTemplate = true; }
 
     public boolean useAsTemplate() { return this.useAsTemplate; }
+
+    public String getDispName() {
+        return dispName;
+    }
+
+    public void setDispName(String dispName) {
+        this.dispName = dispName;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    public void setVmName(String vmName) {
+        this.vmName = vmName;
+    }
 }
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index a3a79de6bf5..3b0e2e5b371 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -432,6 +432,7 @@ public class KVMStorageProcessor implements 
StorageProcessor {
                 if 
(!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), 
primaryStore.getUuid(), path, details)) {
                     s_logger.warn("Failed to connect new volume at path: " + 
path + ", in storage pool id: " + primaryStore.getUuid());
                 }
+                BaseVol.setDispName(template.getName());
 
                 vol = storagePoolMgr.copyPhysicalDisk(BaseVol, path != null ? 
path : volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds(), null, 
volume.getPassphrase(), volume.getProvisioningType());
 
@@ -524,6 +525,8 @@ public class KVMStorageProcessor implements 
StorageProcessor {
             final KVMPhysicalDisk volume = 
secondaryStoragePool.getPhysicalDisk(srcVolumeName);
 
             volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
+            volume.setDispName(srcVol.getName());
+            volume.setVmName(srcVol.getVmName());
 
             final KVMPhysicalDisk newDisk = 
storagePoolMgr.copyPhysicalDisk(volume, path != null ? path : volumeName, 
primaryPool, cmd.getWaitInMillSeconds());
 
@@ -2486,6 +2489,8 @@ public class KVMStorageProcessor implements 
StorageProcessor {
             }
 
             volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
+            volume.setDispName(srcVol.getName());
+            volume.setVmName(srcVol.getVmName());
 
             String destVolumeName = null;
             if (destPrimaryStore.isManaged()) {
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index df6c047e7e2..cad9d429969 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -1402,7 +1402,10 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
          */
 
         KVMStoragePool srcPool = disk.getPool();
-        PhysicalDiskFormat sourceFormat = disk.getFormat();
+        /* Linstor images are always stored as RAW, but Linstor uses qcow2 in 
DB,
+           to support snapshots(backuped) as qcow2 files. */
+        PhysicalDiskFormat sourceFormat = srcPool.getType() != 
StoragePoolType.Linstor ?
+                disk.getFormat() : PhysicalDiskFormat.RAW;
         String sourcePath = disk.getPath();
 
         KVMPhysicalDisk newDisk;
diff --git 
a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
 
b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
index 83a84a91622..659ff7bfe53 100644
--- 
a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
+++ 
b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
@@ -516,6 +516,15 @@ public class LinstorStorageAdaptor implements 
StorageAdaptor {
         final KVMPhysicalDisk dstDisk = destPools.createPhysicalDisk(
             name, QemuImg.PhysicalDiskFormat.RAW, provisioningType, 
disk.getVirtualSize(), null);
 
+        final DevelopersApi api = getLinstorAPI(destPools);
+        final String rscName = LinstorUtil.RSC_PREFIX + name;
+        try {
+            LinstorUtil.applyAuxProps(api, rscName, disk.getDispName(), 
disk.getVmName());
+        } catch (ApiException apiExc) {
+            s_logger.error(String.format("Error setting aux properties for 
%s", rscName));
+            logLinstorAnswers(apiExc.getApiCallRcList());
+        }
+
         s_logger.debug(String.format("Linstor.copyPhysicalDisk: dstPath: %s", 
dstDisk.getPath()));
         final QemuImgFile destFile = new QemuImgFile(dstDisk.getPath());
         destFile.setFormat(dstDisk.getFormat());
diff --git 
a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
 
b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
index 3ca3332fcdd..27904ed441b 100644
--- 
a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
+++ 
b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
@@ -26,7 +26,6 @@ import com.linbit.linstor.api.model.ResourceDefinition;
 import com.linbit.linstor.api.model.ResourceDefinitionCloneRequest;
 import com.linbit.linstor.api.model.ResourceDefinitionCloneStarted;
 import com.linbit.linstor.api.model.ResourceDefinitionCreate;
-import com.linbit.linstor.api.model.ResourceDefinitionModify;
 import com.linbit.linstor.api.model.ResourceGroupSpawn;
 import com.linbit.linstor.api.model.ResourceMakeAvailable;
 import com.linbit.linstor.api.model.Snapshot;
@@ -62,8 +61,8 @@ import com.cloud.resource.ResourceState;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.ResizeVolumePayload;
 import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.VMTemplateStoragePoolVO;
@@ -389,27 +388,6 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
         }
     }
 
-    private void applyAuxProps(DevelopersApi api, String rscName, String 
dispName, String vmName)
-        throws ApiException
-    {
-        ResourceDefinitionModify rdm = new ResourceDefinitionModify();
-        Properties props = new Properties();
-        if (dispName != null)
-        {
-            props.put("Aux/cs-name", dispName);
-        }
-        if (vmName != null)
-        {
-            props.put("Aux/cs-vm-name", vmName);
-        }
-        if (!props.isEmpty())
-        {
-            rdm.setOverrideProps(props);
-            ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
-            checkLinstorAnswersThrow(answers);
-        }
-    }
-
     private String getRscGrp(StoragePoolVO storagePoolVO) {
         return storagePoolVO.getUserInfo() != null && 
!storagePoolVO.getUserInfo().isEmpty() ?
             storagePoolVO.getUserInfo() : "DfltRscGrp";
@@ -427,7 +405,8 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
             ApiCallRcList answers = api.resourceGroupSpawn(rscGrp, 
rscGrpSpawn);
             checkLinstorAnswersThrow(answers);
 
-            applyAuxProps(api, rscName, volName, vmName);
+            answers = LinstorUtil.applyAuxProps(api, rscName, volName, vmName);
+            checkLinstorAnswersThrow(answers);
 
             return LinstorUtil.getDevicePath(api, rscName);
         } catch (ApiException apiEx)
@@ -499,7 +478,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
                     resizeResource(linstorApi, rscName, volumeInfo.getSize());
                 }
 
-                applyAuxProps(linstorApi, rscName, volumeInfo.getName(), 
volumeInfo.getAttachedVmName());
+                LinstorUtil.applyAuxProps(linstorApi, rscName, 
volumeInfo.getName(), volumeInfo.getAttachedVmName());
                 applyQoSSettings(storagePoolVO, linstorApi, rscName, 
volumeInfo.getMaxIops());
 
                 return LinstorUtil.getDevicePath(linstorApi, rscName);
@@ -551,7 +530,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
             answers = linstorApi.resourceSnapshotRestore(cloneRes, snapName, 
snapshotRestore);
             checkLinstorAnswersThrow(answers);
 
-            applyAuxProps(linstorApi, rscName, volumeVO.getName(), null);
+            LinstorUtil.applyAuxProps(linstorApi, rscName, volumeVO.getName(), 
null);
             applyQoSSettings(storagePoolVO, linstorApi, rscName, 
volumeVO.getMaxIops());
 
             return LinstorUtil.getDevicePath(linstorApi, rscName);
@@ -833,7 +812,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
                 VolumeInfo volume = sinfo.getBaseVolume();
                 deleteSnapshot(
                     srcData.getDataStore(),
-                    LinstorUtil.RSC_PREFIX + volume.getUuid(),
+                    LinstorUtil.RSC_PREFIX + volume.getPath(),
                     LinstorUtil.RSC_PREFIX + sinfo.getUuid());
             }
             res = new CopyCommandResult(null, answer);
@@ -969,7 +948,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
         VolumeInfo srcVolInfo = (VolumeInfo) srcData;
         final StoragePoolVO pool = 
_storagePoolDao.findById(srcVolInfo.getDataStore().getId());
         final DevelopersApi api = 
LinstorUtil.getLinstorAPI(pool.getHostAddress());
-        final String rscName = LinstorUtil.RSC_PREFIX + srcVolInfo.getUuid();
+        final String rscName = LinstorUtil.RSC_PREFIX + srcVolInfo.getPath();
 
         VolumeObjectTO to = (VolumeObjectTO) srcVolInfo.getTO();
         // patch source format
@@ -1082,7 +1061,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements 
PrimaryDataStoreDriver
         options.put("volumeSize", snapshotObject.getBaseVolume().getSize() + 
"");
 
         try {
-            final String rscName = LinstorUtil.RSC_PREFIX + 
snapshotObject.getBaseVolume().getUuid();
+            final String rscName = LinstorUtil.RSC_PREFIX + 
snapshotObject.getBaseVolume().getPath();
             String snapshotName = setCorrectSnapshotPath(api, rscName, 
snapshotObject);
 
             CopyCommand cmd = new LinstorBackupSnapshotCommand(
diff --git 
a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
 
b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
index b857b4ebb83..9aa6f151abc 100644
--- 
a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
+++ 
b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java
@@ -22,8 +22,10 @@ import com.linbit.linstor.api.DevelopersApi;
 import com.linbit.linstor.api.model.ApiCallRc;
 import com.linbit.linstor.api.model.ApiCallRcList;
 import com.linbit.linstor.api.model.Node;
+import com.linbit.linstor.api.model.Properties;
 import com.linbit.linstor.api.model.ProviderKind;
 import com.linbit.linstor.api.model.Resource;
+import com.linbit.linstor.api.model.ResourceDefinitionModify;
 import com.linbit.linstor.api.model.ResourceGroup;
 import com.linbit.linstor.api.model.ResourceWithVolumes;
 import com.linbit.linstor.api.model.StoragePool;
@@ -239,4 +241,26 @@ public class LinstorUtil {
         s_logger.error(errMsg);
         throw new CloudRuntimeException("Linstor: " + errMsg);
     }
+
+    public static ApiCallRcList applyAuxProps(DevelopersApi api, String 
rscName, String dispName, String vmName)
+            throws ApiException
+    {
+        ResourceDefinitionModify rdm = new ResourceDefinitionModify();
+        Properties props = new Properties();
+        if (dispName != null)
+        {
+            props.put("Aux/cs-name", dispName);
+        }
+        if (vmName != null)
+        {
+            props.put("Aux/cs-vm-name", vmName);
+        }
+        ApiCallRcList answers = new ApiCallRcList();
+        if (!props.isEmpty())
+        {
+            rdm.setOverrideProps(props);
+            answers = api.resourceDefinitionModify(rscName, rdm);
+        }
+        return answers;
+    }
 }
diff --git 
a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/snapshot/LinstorVMSnapshotStrategy.java
 
b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/snapshot/LinstorVMSnapshotStrategy.java
index af7b6978db5..daad3d5dc57 100644
--- 
a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/snapshot/LinstorVMSnapshotStrategy.java
+++ 
b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/snapshot/LinstorVMSnapshotStrategy.java
@@ -239,7 +239,7 @@ public class LinstorVMSnapshotStrategy extends 
DefaultVMSnapshotStrategy {
         final String snapshotName = vmSnapshotVO.getName();
         final List<String> failedToDelete = new ArrayList<>();
         for (VolumeObjectTO volumeObjectTO : volumeTOs) {
-            final String rscName = LinstorUtil.RSC_PREFIX + 
volumeObjectTO.getUuid();
+            final String rscName = LinstorUtil.RSC_PREFIX + 
volumeObjectTO.getPath();
             String err = linstorDeleteSnapshot(api, rscName, snapshotName);
 
             if (err != null)
@@ -292,7 +292,7 @@ public class LinstorVMSnapshotStrategy extends 
DefaultVMSnapshotStrategy {
         final String snapshotName = vmSnapshotVO.getName();
 
         for (VolumeObjectTO volumeObjectTO : volumeTOs) {
-            final String rscName = LinstorUtil.RSC_PREFIX + 
volumeObjectTO.getUuid();
+            final String rscName = LinstorUtil.RSC_PREFIX + 
volumeObjectTO.getPath();
             String err = linstorRevertSnapshot(api, rscName, snapshotName);
             if (err != null) {
                 throw new CloudRuntimeException(String.format(

Reply via email to