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

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


The following commit(s) were added to refs/heads/main by this push:
     new cb4848bc1a6 Add support to RBD erasure code pools (#9808)
cb4848bc1a6 is described below

commit cb4848bc1a603dd046b21c9c65e085c0e3110092
Author: Bryan Lima <[email protected]>
AuthorDate: Wed Apr 2 13:19:00 2025 +0200

    Add support to RBD erasure code pools (#9808)
    
    * Readd filename string on qemuimg create
    
    * Remove empty object on the data pool details of storage pools with no 
data pool
    
    * Only use the method createPhysicalDiskByLibVirt with RBD when the pool is 
of erasure code type. Also added javadoc for createPhysicalDisk method
    
    * Change literal '/' string to File.separator
    
    * Add support for erasure code pools
    
    * Fix null on putAll
---
 .../api/response/StoragePoolResponse.java          | 12 ++++
 .../datastore/provider/DefaultHostListener.java    |  8 ++-
 ...atePrivateTemplateFromVolumeCommandWrapper.java |  4 +-
 .../LibvirtGetVolumesOnStorageCommandWrapper.java  |  6 +-
 .../kvm/storage/IscsiAdmStorageAdaptor.java        |  4 +-
 .../hypervisor/kvm/storage/KVMPhysicalDisk.java    | 18 ++++-
 .../kvm/storage/KVMStoragePoolManager.java         | 43 ++++++------
 .../kvm/storage/KVMStorageProcessor.java           |  8 +--
 .../kvm/storage/LibvirtStorageAdaptor.java         | 81 ++++++++++++++++------
 .../hypervisor/kvm/storage/LibvirtStoragePool.java |  8 ++-
 .../kvm/storage/StoragePoolInformation.java        | 75 ++++++++++++++++++++
 .../kvm/storage/KVMPhysicalDiskTest.java           | 64 ++++++++++++-----
 .../StorPoolDownloadVolumeCommandWrapper.java      |  6 +-
 .../java/com/cloud/api/query/QueryManagerImpl.java | 40 +++++++----
 ui/public/locales/en.json                          |  2 +
 ui/public/locales/pt_BR.json                       |  2 +
 ui/src/components/view/DetailsTab.vue              |  9 ++-
 ui/src/config/section/infra/primaryStorages.js     |  2 +-
 ui/src/views/infra/AddPrimaryStorage.vue           | 13 ++++
 ui/src/views/infra/zone/ZoneWizardAddResources.vue | 14 +++-
 ui/src/views/infra/zone/ZoneWizardLaunchZone.vue   |  4 ++
 21 files changed, 312 insertions(+), 111 deletions(-)

diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/StoragePoolResponse.java 
b/api/src/main/java/org/apache/cloudstack/api/response/StoragePoolResponse.java
index 676803ea86b..51efb6d42cb 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/response/StoragePoolResponse.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/response/StoragePoolResponse.java
@@ -149,6 +149,10 @@ public class StoragePoolResponse extends 
BaseResponseWithAnnotations {
     @Param(description = "whether this pool is managed or not")
     private Boolean managed;
 
+    @SerializedName(ApiConstants.DETAILS)
+    @Param(description = "the storage pool details")
+    private Map<String, String> details;
+
     public Map<String, String> getCaps() {
         return caps;
     }
@@ -407,4 +411,12 @@ public class StoragePoolResponse extends 
BaseResponseWithAnnotations {
     public void setManaged(Boolean managed) {
         this.managed = managed;
     }
+
+    public Map<String, String> getDetails() {
+        return details;
+    }
+
+    public void setDetails(Map<String, String> details) {
+        this.details = details;
+    }
 }
diff --git 
a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
 
b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
index 1afc1a68b44..331b1f3ce5b 100644
--- 
a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
+++ 
b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
@@ -43,7 +43,6 @@ import com.cloud.storage.StoragePool;
 import com.cloud.storage.StoragePoolHostVO;
 import com.cloud.storage.StorageService;
 import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.utils.Pair;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -60,6 +59,7 @@ import javax.inject.Inject;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 public class DefaultHostListener implements HypervisorHostListener {
     protected Logger logger = LogManager.getLogger(getClass());
@@ -133,9 +133,11 @@ public class DefaultHostListener implements 
HypervisorHostListener {
     @Override
     public boolean hostConnect(long hostId, long poolId) throws 
StorageConflictException {
         StoragePool pool = (StoragePool) 
this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
-        Pair<Map<String, String>, Boolean> nfsMountOpts = 
storageManager.getStoragePoolNFSMountOpts(pool, null);
+        Map<String, String> detailsMap = 
storagePoolDetailsDao.listDetailsKeyPairs(poolId);
+        Map<String, String> nfsMountOpts = 
storageManager.getStoragePoolNFSMountOpts(pool, null).first();
 
-        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, 
pool, nfsMountOpts.first());
+        Optional.ofNullable(nfsMountOpts).ifPresent(detailsMap::putAll);
+        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, 
pool, detailsMap);
         cmd.setWait(modifyStoragePoolCommandWait);
         HostVO host = hostDao.findById(hostId);
         logger.debug("Sending modify storage pool command to agent: {} for 
storage pool: {} with timeout {} seconds", host, pool, cmd.getWait());
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
index de35a1251bb..9fb282866cb 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
@@ -108,9 +108,7 @@ public final class 
LibvirtCreatePrivateTemplateFromVolumeCommandWrapper extends
             } else {
                 logger.debug("Converting RBD disk " + disk.getPath() + " into 
template " + command.getUniqueName());
 
-                final QemuImgFile srcFile =
-                        new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), 
primary.getSourcePort(), primary.getAuthUserName(),
-                                primary.getAuthSecret(), disk.getPath()));
+                final QemuImgFile srcFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary, disk.getPath()));
                 srcFile.setFormat(PhysicalDiskFormat.RAW);
 
                 final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + 
command.getUniqueName() + ".qcow2");
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumesOnStorageCommandWrapper.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumesOnStorageCommandWrapper.java
index 821a80f5cca..0f0c6488bb3 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumesOnStorageCommandWrapper.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumesOnStorageCommandWrapper.java
@@ -161,11 +161,7 @@ public final class 
LibvirtGetVolumesOnStorageCommandWrapper extends CommandWrapp
             QemuImg qemu = new QemuImg(0);
             QemuImgFile qemuFile = new QemuImgFile(disk.getPath(), 
disk.getFormat());
             if (StoragePoolType.RBD.equals(pool.getType())) {
-                String rbdDestFile = 
KVMPhysicalDisk.RBDStringBuilder(pool.getSourceHost(),
-                        pool.getSourcePort(),
-                        pool.getAuthUserName(),
-                        pool.getAuthSecret(),
-                        disk.getPath());
+                String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(pool, 
disk.getPath());
                 qemuFile = new QemuImgFile(rbdDestFile, disk.getFormat());
             }
             return qemu.info(qemuFile, secure);
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
index 6185c69032f..ba689d5107f 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
@@ -410,9 +410,7 @@ public class IscsiAdmStorageAdaptor implements 
StorageAdaptor {
         KVMStoragePool srcPool = srcDisk.getPool();
 
         if (srcPool.getType() == StoragePoolType.RBD) {
-            srcFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), 
srcPool.getSourcePort(),
-                                                                       
srcPool.getAuthUserName(), srcPool.getAuthSecret(),
-                                                                       
srcDisk.getPath()),srcDisk.getFormat());
+            srcFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool, srcDisk.getPath()), 
srcDisk.getFormat());
         } else {
             srcFile = new QemuImgFile(srcDisk.getPath(), srcDisk.getFormat());
         }
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 9d9a6415e27..ab02e16603d 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
@@ -23,6 +23,7 @@ import org.apache.commons.lang3.StringUtils;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 public class KVMPhysicalDisk {
     private String path;
@@ -32,10 +33,17 @@ public class KVMPhysicalDisk {
     private String vmName;
     private boolean useAsTemplate;
 
-    public static String RBDStringBuilder(String monHost, int monPort, String 
authUserName, String authSecret, String image) {
-        String rbdOpts;
+    public static final String RBD_DEFAULT_DATA_POOL = "rbd_default_data_pool";
 
-        rbdOpts = "rbd:" + image;
+    public static String RBDStringBuilder(KVMStoragePool storagePool, String 
image) {
+        String monHost = storagePool.getSourceHost();
+        int monPort = storagePool.getSourcePort();
+        String authUserName = storagePool.getAuthUserName();
+        String authSecret = storagePool.getAuthSecret();
+        Map<String, String> details = storagePool.getDetails();
+        String dataPool = (details == null) ? null : 
details.get(RBD_DEFAULT_DATA_POOL);
+
+        String rbdOpts = "rbd:" + image;
         rbdOpts += ":mon_host=" + composeOptionForMonHosts(monHost, monPort);
 
         if (authUserName == null) {
@@ -46,6 +54,10 @@ public class KVMPhysicalDisk {
             rbdOpts += ":key=" + authSecret;
         }
 
+        if (dataPool != null) {
+            rbdOpts += String.format(":rbd_default_data_pool=%s", dataPool);
+        }
+
         rbdOpts += ":rbd_default_format=2";
         rbdOpts += ":client_mount_timeout=30";
 
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
index e27547acbb2..ed389a1cf73 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
@@ -53,28 +53,6 @@ import com.cloud.vm.VirtualMachine;
 public class KVMStoragePoolManager {
     protected Logger logger = LogManager.getLogger(getClass());
 
-    private class StoragePoolInformation {
-        String name;
-        String host;
-        int port;
-        String path;
-        String userInfo;
-        boolean type;
-        StoragePoolType poolType;
-        Map<String, String> details;
-
-        public StoragePoolInformation(String name, String host, int port, 
String path, String userInfo, StoragePoolType poolType, Map<String, String> 
details, boolean type) {
-            this.name = name;
-            this.host = host;
-            this.port = port;
-            this.path = path;
-            this.userInfo = userInfo;
-            this.type = type;
-            this.poolType = poolType;
-            this.details = details;
-        }
-    }
-
     private KVMHAMonitor _haMonitor;
     private final Map<String, StoragePoolInformation> _storagePools = new 
ConcurrentHashMap<String, StoragePoolInformation>();
     private final Map<String, StorageAdaptor> _storageMapper = new 
HashMap<String, StorageAdaptor>();
@@ -303,14 +281,33 @@ public class KVMStoragePoolManager {
         } catch (Exception e) {
             StoragePoolInformation info = _storagePools.get(uuid);
             if (info != null) {
-                pool = createStoragePool(info.name, info.host, info.port, 
info.path, info.userInfo, info.poolType, info.details, info.type);
+                pool = createStoragePool(info.getName(), info.getHost(), 
info.getPort(), info.getPath(), info.getUserInfo(), info.getPoolType(), 
info.getDetails(), info.isType());
             } else {
                 throw new CloudRuntimeException("Could not fetch storage pool 
" + uuid + " from libvirt due to " + e.getMessage());
             }
         }
+
+        if (pool instanceof LibvirtStoragePool) {
+            addPoolDetails(uuid, (LibvirtStoragePool) pool);
+        }
+
         return pool;
     }
 
+    /**
+     * As the class {@link LibvirtStoragePool} is constrained to the {@link 
org.libvirt.StoragePool} class, there is no way of saving a generic parameter 
such as the details, hence,
+     * this method was created to always make available the details of libvirt 
primary storages for when they are needed.
+     */
+    private void addPoolDetails(String uuid, LibvirtStoragePool pool) {
+        StoragePoolInformation storagePoolInformation = 
_storagePools.get(uuid);
+        Map<String, String> details = storagePoolInformation.getDetails();
+
+        if (MapUtils.isNotEmpty(details)) {
+            logger.trace("Adding the details {} to the pool with UUID {}.", 
details, uuid);
+            pool.setDetails(details);
+        }
+    }
+
     public KVMStoragePool getStoragePoolByURI(String uri) {
         URI storageUri = null;
 
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 cdb523a50fd..c35c7e9a62b 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
@@ -667,9 +667,7 @@ public class KVMStorageProcessor implements 
StorageProcessor {
             } else {
                 logger.debug("Converting RBD disk " + disk.getPath() + " into 
template " + templateName);
 
-                final QemuImgFile srcFile =
-                        new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), 
primary.getSourcePort(), primary.getAuthUserName(),
-                                primary.getAuthSecret(), disk.getPath()));
+                final QemuImgFile srcFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary, disk.getPath()));
                 srcFile.setFormat(PhysicalDiskFormat.RAW);
 
                 final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + 
templateName + ".qcow2");
@@ -1022,9 +1020,7 @@ public class KVMStorageProcessor implements 
StorageProcessor {
                     logger.debug("Attempting to create " + 
snapDir.getAbsolutePath() + " recursively for snapshot storage");
                     FileUtils.forceMkdir(snapDir);
 
-                    final QemuImgFile srcFile =
-                            new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primaryPool.getSourceHost(), 
primaryPool.getSourcePort(), primaryPool.getAuthUserName(),
-                                    primaryPool.getAuthSecret(), rbdSnapshot));
+                    final QemuImgFile srcFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primaryPool, rbdSnapshot));
                     srcFile.setFormat(snapshotDisk.getFormat());
 
                     final QemuImgFile destFile = new QemuImgFile(snapshotFile);
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 f3731459f89..e93f82ac4dd 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
@@ -960,17 +960,55 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
         }
     }
 
+    /**
+     * Creates a physical disk depending on the {@link StoragePoolType}:
+     * <ul>
+     *     <li>
+     *         <b>{@link StoragePoolType#RBD}</b>
+     *         <ul>
+     *             <li>
+     *                 If it is an erasure code pool, utilizes QemuImg to 
create the physical disk through the method
+     *             {@link 
LibvirtStorageAdaptor#createPhysicalDiskByQemuImg(String, KVMStoragePool, 
PhysicalDiskFormat, Storage.ProvisioningType, long, byte[])}
+     *             </li>
+     *             <li>
+     *                 Otherwise, utilize Libvirt to create the physical disk 
through the method
+     *                 {@link 
LibvirtStorageAdaptor#createPhysicalDiskByLibVirt(String, KVMStoragePool, 
PhysicalDiskFormat, Storage.ProvisioningType, long)}
+     *             </li>
+     *         </ul>
+     *     </li>
+     *     <li>
+     *         {@link StoragePoolType#NetworkFilesystem} and {@link 
StoragePoolType#Filesystem}
+     *         <ul>
+     *             <li>
+     *                 If the format is {@link PhysicalDiskFormat#QCOW2} or 
{@link PhysicalDiskFormat#RAW}, utilizes QemuImg to create the physical disk 
through the method
+     *             {@link 
LibvirtStorageAdaptor#createPhysicalDiskByQemuImg(String, KVMStoragePool, 
PhysicalDiskFormat, Storage.ProvisioningType, long, byte[])}
+     *             </li>
+     *             <li>
+     *                 If the format is {@link PhysicalDiskFormat#DIR} or 
{@link PhysicalDiskFormat#TAR}, utilize Libvirt to create the physical disk 
through the method
+     *                 {@link 
LibvirtStorageAdaptor#createPhysicalDiskByLibVirt(String, KVMStoragePool, 
PhysicalDiskFormat, Storage.ProvisioningType, long)}
+     *             </li>
+     *         </ul>
+     *     </li>
+     *     <li>
+     *         For the rest of the {@link StoragePoolType} types, utilizes the 
Libvirt method
+     *         {@link 
LibvirtStorageAdaptor#createPhysicalDiskByLibVirt(String, KVMStoragePool, 
PhysicalDiskFormat, Storage.ProvisioningType, long)}
+     *     </li>
+     * </ul>
+     */
     @Override
     public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool,
             PhysicalDiskFormat format, Storage.ProvisioningType 
provisioningType, long size, byte[] passphrase) {
 
-        logger.info("Attempting to create volume " + name + " (" + 
pool.getType().toString() + ") in pool "
-                + pool.getUuid() + " with size " + toHumanReadableSize(size));
+        logger.info("Attempting to create volume {} ({}) in pool {} with size 
{}", name, pool.getType().toString(), pool.getUuid(), 
toHumanReadableSize(size));
 
         StoragePoolType poolType = pool.getType();
-        if (poolType.equals(StoragePoolType.RBD)) {
-            return createPhysicalDiskByLibVirt(name, pool, 
PhysicalDiskFormat.RAW, provisioningType, size);
-        } else if (poolType.equals(StoragePoolType.NetworkFilesystem) || 
poolType.equals(StoragePoolType.Filesystem)) {
+        if (StoragePoolType.RBD.equals(poolType)) {
+            Map<String, String> details = pool.getDetails();
+            String dataPool = (details == null) ? null : 
details.get(KVMPhysicalDisk.RBD_DEFAULT_DATA_POOL);
+
+            return (dataPool == null) ?  createPhysicalDiskByLibVirt(name, 
pool, PhysicalDiskFormat.RAW, provisioningType, size) :
+                    createPhysicalDiskByQemuImg(name, pool, 
PhysicalDiskFormat.RAW, provisioningType, size, passphrase);
+        } else if (StoragePoolType.NetworkFilesystem.equals(poolType) || 
StoragePoolType.Filesystem.equals(poolType)) {
             switch (format) {
                 case QCOW2:
                 case RAW:
@@ -1018,18 +1056,25 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
     }
 
 
-    private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, 
KVMStoragePool pool,
-            PhysicalDiskFormat format, Storage.ProvisioningType 
provisioningType, long size, byte[] passphrase) {
-        String volPath = pool.getLocalPath() + "/" + name;
+    private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, 
KVMStoragePool pool, PhysicalDiskFormat format, Storage.ProvisioningType 
provisioningType, long size,
+                                                        byte[] passphrase) {
+        String volPath;
         String volName = name;
         long virtualSize = 0;
         long actualSize = 0;
         QemuObject.EncryptFormat encryptFormat = null;
         List<QemuObject> passphraseObjects = new ArrayList<>();
-
         final int timeout = 0;
+        QemuImgFile destFile;
+
+        if (StoragePoolType.RBD.equals(pool.getType())) {
+            volPath = pool.getSourceDir() + File.separator + name;
+            destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(pool, 
volPath));
+        } else {
+            volPath = pool.getLocalPath() + File.separator + name;
+            destFile = new QemuImgFile(volPath);
+        }
 
-        QemuImgFile destFile = new QemuImgFile(volPath);
         destFile.setFormat(format);
         destFile.setSize(size);
         Map<String, String> options = new HashMap<String, String>();
@@ -1312,11 +1357,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
 
 
         QemuImgFile srcFile;
-        QemuImgFile destFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
-                destPool.getSourcePort(),
-                destPool.getAuthUserName(),
-                destPool.getAuthSecret(),
-                disk.getPath()));
+        QemuImgFile destFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool, disk.getPath()));
         destFile.setFormat(format);
 
         if (srcPool.getType() != StoragePoolType.RBD) {
@@ -1591,11 +1632,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
             try {
                 srcFile = new QemuImgFile(sourcePath, sourceFormat);
                 String rbdDestPath = destPool.getSourceDir() + "/" + name;
-                String rbdDestFile = 
KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
-                        destPool.getSourcePort(),
-                        destPool.getAuthUserName(),
-                        destPool.getAuthSecret(),
-                        rbdDestPath);
+                String rbdDestFile = 
KVMPhysicalDisk.RBDStringBuilder(destPool, rbdDestPath);
                 destFile = new QemuImgFile(rbdDestFile, destFormat);
 
                 logger.debug("Starting copy from source image " + 
srcFile.getFileName() + " to RBD image " + rbdDestPath);
@@ -1638,9 +1675,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
                 We let Qemu-Img do the work here. Although we could work with 
librbd and have that do the cloning
                 it doesn't benefit us. It's better to keep the current code in 
place which works
              */
-            srcFile =
-                    new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), 
srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(),
-                            sourcePath));
+            srcFile = new 
QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool, sourcePath));
             srcFile.setFormat(sourceFormat);
             destFile = new QemuImgFile(destPath);
             destFile.setFormat(destFormat);
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
index 8e5af7c613d..ab39f7bc6ff 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
@@ -56,8 +56,8 @@ public class LibvirtStoragePool implements KVMStoragePool {
     protected String authSecret;
     protected String sourceHost;
     protected int sourcePort;
-
     protected String sourceDir;
+    protected Map<String, String> details;
 
     public LibvirtStoragePool(String uuid, String name, StoragePoolType type, 
StorageAdaptor adaptor, StoragePool pool) {
         this.uuid = uuid;
@@ -311,7 +311,11 @@ public class LibvirtStoragePool implements KVMStoragePool {
 
     @Override
     public Map<String, String> getDetails() {
-        return null;
+        return this.details;
+    }
+
+    public void setDetails(Map<String, String> details) {
+        this.details = details;
     }
 
     @Override
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StoragePoolInformation.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StoragePoolInformation.java
new file mode 100644
index 00000000000..f330c9f24f0
--- /dev/null
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StoragePoolInformation.java
@@ -0,0 +1,75 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.kvm.storage;
+
+import com.cloud.storage.Storage;
+
+import java.util.Map;
+
+class StoragePoolInformation {
+    private String name;
+    private String host;
+    private int port;
+    private String path;
+    private String userInfo;
+    private boolean type;
+    private Storage.StoragePoolType poolType;
+    private Map<String, String> details;
+
+    public StoragePoolInformation(String name, String host, int port, String 
path, String userInfo, Storage.StoragePoolType poolType, Map<String, String> 
details, boolean type) {
+        this.name = name;
+        this.host = host;
+        this.port = port;
+        this.path = path;
+        this.userInfo = userInfo;
+        this.type = type;
+        this.poolType = poolType;
+        this.details = details;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public String getUserInfo() {
+        return userInfo;
+    }
+
+    public boolean isType() {
+        return type;
+    }
+
+    public Storage.StoragePoolType getPoolType() {
+        return poolType;
+    }
+
+    public Map<String, String> getDetails() {
+        return details;
+    }
+}
diff --git 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
index 187565c0602..098f3e1b8bd 100644
--- 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
+++ 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
@@ -17,43 +17,73 @@
 package com.cloud.hypervisor.kvm.storage;
 
 import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 
-import junit.framework.TestCase;
 import org.mockito.junit.MockitoJUnitRunner;
 
-
 @RunWith(MockitoJUnitRunner.class)
-public class KVMPhysicalDiskTest extends TestCase {
+public class KVMPhysicalDiskTest {
+    @Mock
+    KVMStoragePool kvmStoragePoolMock;
+
+    private final String authUserName = "admin";
+
+    private final String authSecret = "supersecret";
 
     @Test
     public void testRBDStringBuilder() {
-        assertEquals(KVMPhysicalDisk.RBDStringBuilder("ceph-monitor", 8000, 
"admin", "supersecret", "volume1"),
-                     
"rbd:volume1:mon_host=ceph-monitor\\:8000:auth_supported=cephx:id=admin:key=supersecret:rbd_default_format=2:client_mount_timeout=30");
+        String monHosts = "ceph-monitor";
+        int monPort = 8000;
+
+        Mockito.doReturn(monHosts).when(kvmStoragePoolMock).getSourceHost();
+        Mockito.doReturn(monPort).when(kvmStoragePoolMock).getSourcePort();
+        
Mockito.doReturn(authUserName).when(kvmStoragePoolMock).getAuthUserName();
+        Mockito.doReturn(authSecret).when(kvmStoragePoolMock).getAuthSecret();
+
+        String expected = 
"rbd:volume1:mon_host=ceph-monitor\\:8000:auth_supported=cephx:id=admin:key=supersecret:rbd_default_format=2:client_mount_timeout=30";
+        String result = KVMPhysicalDisk.RBDStringBuilder(kvmStoragePoolMock, 
"volume1");
+
+        Assert.assertEquals(expected, result);
     }
 
     @Test
     public void testRBDStringBuilder2() {
         String monHosts = "ceph-monitor1,ceph-monitor2,ceph-monitor3";
         int monPort = 3300;
+
+        Mockito.doReturn(monHosts).when(kvmStoragePoolMock).getSourceHost();
+        Mockito.doReturn(monPort).when(kvmStoragePoolMock).getSourcePort();
+        
Mockito.doReturn(authUserName).when(kvmStoragePoolMock).getAuthUserName();
+        Mockito.doReturn(authSecret).when(kvmStoragePoolMock).getAuthSecret();
+
         String expected = "rbd:volume1:" +
                 
"mon_host=ceph-monitor1\\:3300\\;ceph-monitor2\\:3300\\;ceph-monitor3\\:3300:" +
                 
"auth_supported=cephx:id=admin:key=supersecret:rbd_default_format=2:client_mount_timeout=30";
-        String actualResult = KVMPhysicalDisk.RBDStringBuilder(monHosts, 
monPort, "admin", "supersecret", "volume1");
-        assertEquals(expected, actualResult);
+        String actualResult = 
KVMPhysicalDisk.RBDStringBuilder(kvmStoragePoolMock, "volume1");
+
+        Assert.assertEquals(expected, actualResult);
     }
 
     @Test
     public void testRBDStringBuilder3() {
         String monHosts = "[fc00:1234::1],[fc00:1234::2],[fc00:1234::3]";
         int monPort = 3300;
+
+        Mockito.doReturn(monHosts).when(kvmStoragePoolMock).getSourceHost();
+        Mockito.doReturn(monPort).when(kvmStoragePoolMock).getSourcePort();
+        
Mockito.doReturn(authUserName).when(kvmStoragePoolMock).getAuthUserName();
+        Mockito.doReturn(authSecret).when(kvmStoragePoolMock).getAuthSecret();
+
         String expected = "rbd:volume1:" +
                 
"mon_host=[fc00\\:1234\\:\\:1]\\:3300\\;[fc00\\:1234\\:\\:2]\\:3300\\;[fc00\\:1234\\:\\:3]\\:3300:"
 +
                 
"auth_supported=cephx:id=admin:key=supersecret:rbd_default_format=2:client_mount_timeout=30";
-        String actualResult = KVMPhysicalDisk.RBDStringBuilder(monHosts, 
monPort, "admin", "supersecret", "volume1");
-        assertEquals(expected, actualResult);
+        String actualResult = 
KVMPhysicalDisk.RBDStringBuilder(kvmStoragePoolMock, "volume1");
+
+        Assert.assertEquals(expected, actualResult);
     }
 
     @Test
@@ -64,18 +94,18 @@ public class KVMPhysicalDiskTest extends TestCase {
         LibvirtStoragePool pool = Mockito.mock(LibvirtStoragePool.class);
 
         KVMPhysicalDisk disk = new KVMPhysicalDisk(path, name, pool);
-        assertEquals(disk.getName(), name);
-        assertEquals(disk.getPath(), path);
-        assertEquals(disk.getPool(), pool);
-        assertEquals(disk.getSize(), 0);
-        assertEquals(disk.getVirtualSize(), 0);
+        Assert.assertEquals(disk.getName(), name);
+        Assert.assertEquals(disk.getPath(), path);
+        Assert.assertEquals(disk.getPool(), pool);
+        Assert.assertEquals(disk.getSize(), 0);
+        Assert.assertEquals(disk.getVirtualSize(), 0);
 
         disk.setSize(1024);
         disk.setVirtualSize(2048);
-        assertEquals(disk.getSize(), 1024);
-        assertEquals(disk.getVirtualSize(), 2048);
+        Assert.assertEquals(disk.getSize(), 1024);
+        Assert.assertEquals(disk.getVirtualSize(), 2048);
 
         disk.setFormat(PhysicalDiskFormat.RAW);
-        assertEquals(disk.getFormat(), PhysicalDiskFormat.RAW);
+        Assert.assertEquals(disk.getFormat(), PhysicalDiskFormat.RAW);
     }
 }
diff --git 
a/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolDownloadVolumeCommandWrapper.java
 
b/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolDownloadVolumeCommandWrapper.java
index 37284b597d2..1679e646e18 100644
--- 
a/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolDownloadVolumeCommandWrapper.java
+++ 
b/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolDownloadVolumeCommandWrapper.java
@@ -114,11 +114,7 @@ public final class StorPoolDownloadVolumeCommandWrapper 
extends CommandWrapper<S
             if (isRBDPool) {
                 KVMStoragePool srcPool = srcDisk.getPool();
                 String rbdDestPath = srcPool.getSourceDir() + "/" + 
srcDisk.getName();
-                srcPath = 
KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
-                        srcPool.getSourcePort(),
-                        srcPool.getAuthUserName(),
-                        srcPool.getAuthSecret(),
-                        rbdDestPath);
+                srcPath = KVMPhysicalDisk.RBDStringBuilder(srcPool, 
rbdDestPath);
             } else {
                 srcPath = srcDisk.getPath();
             }
diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java 
b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
index cbbf664014d..a6ea75b47fe 100644
--- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
@@ -165,6 +165,7 @@ import 
org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.EnumUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 
@@ -3158,28 +3159,41 @@ public class QueryManagerImpl extends 
MutualExclusiveIdsManagerBase implements Q
         List<StoragePoolResponse> poolResponses = 
ViewResponseHelper.createStoragePoolResponse(getCustomStats, 
storagePools.first().toArray(new 
StoragePoolJoinVO[storagePools.first().size()]));
         Map<String, Long> poolUuidToIdMap = 
storagePools.first().stream().collect(Collectors.toMap(StoragePoolJoinVO::getUuid,
 StoragePoolJoinVO::getId, (a, b) -> a));
         for (StoragePoolResponse poolResponse : poolResponses) {
+            Long poolId = poolUuidToIdMap.get(poolResponse.getId());
             DataStore store = 
dataStoreManager.getPrimaryDataStore(poolResponse.getId());
+
             if (store != null) {
-                DataStoreDriver driver = store.getDriver();
-                if (driver != null && driver.getCapabilities() != null) {
-                    Map<String, String> caps = driver.getCapabilities();
-                    if 
(Storage.StoragePoolType.NetworkFilesystem.toString().equals(poolResponse.getType())
 &&
-                        
HypervisorType.VMware.toString().equals(poolResponse.getHypervisor())) {
-                        StoragePoolDetailVO detail = 
_storagePoolDetailsDao.findDetail(poolUuidToIdMap.get(poolResponse.getId()), 
Storage.Capability.HARDWARE_ACCELERATION.toString());
-                        if (detail != null) {
-                            
caps.put(Storage.Capability.HARDWARE_ACCELERATION.toString(), 
detail.getValue());
-                        }
-                    }
-                    poolResponse.setCaps(caps);
-                }
+                addPoolDetailsAndCapabilities(poolResponse, store, poolId);
             }
-            setPoolResponseNFSMountOptions(poolResponse, 
poolUuidToIdMap.get(poolResponse.getId()));
+
+            setPoolResponseNFSMountOptions(poolResponse, poolId);
         }
 
         response.setResponses(poolResponses, storagePools.second());
         return response;
     }
 
+    private void addPoolDetailsAndCapabilities(StoragePoolResponse 
poolResponse, DataStore store, Long poolId) {
+        Map<String, String> details = 
_storagePoolDetailsDao.listDetailsKeyPairs(store.getId(), true);
+        poolResponse.setDetails(details);
+
+        DataStoreDriver driver = store.getDriver();
+        if (ObjectUtils.anyNull(driver, driver.getCapabilities())) {
+            return;
+        }
+
+        Map<String, String> caps = driver.getCapabilities();
+        if 
(Storage.StoragePoolType.NetworkFilesystem.toString().equals(poolResponse.getType())
 && HypervisorType.VMware.toString().equals(poolResponse.getHypervisor())) {
+            StoragePoolDetailVO detail = 
_storagePoolDetailsDao.findDetail(poolId, 
Storage.Capability.HARDWARE_ACCELERATION.toString());
+            if (detail != null) {
+                caps.put(Storage.Capability.HARDWARE_ACCELERATION.toString(), 
detail.getValue());
+            }
+        }
+        poolResponse.setCaps(caps);
+    }
+
+
+
     private Pair<List<StoragePoolJoinVO>, Integer> 
searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) {
         ScopeType scopeType = 
ScopeType.validateAndGetScopeType(cmd.getScope());
         StoragePoolStatus status = 
StoragePoolStatus.validateAndGetStatus(cmd.getStatus());
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index 2df2ebf5903..b4ea945cd25 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -665,6 +665,8 @@
 "label.dark.mode": "Dark mode",
 "label.dashboard": "Dashboard",
 "label.data.disk": "Data disk",
+"label.data.pool": "Data pool",
+"label.data.pool.description": "Data pool is required when using a Ceph pool 
with erasure code",
 "label.data.disk.offering": "Data disk offering",
 "label.date": "Date",
 "label.datetime.filter.period": "From <b>{startDate}</b> to <b>{endDate}</b>",
diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json
index dc72ec023bb..aadbd2fedc3 100644
--- a/ui/public/locales/pt_BR.json
+++ b/ui/public/locales/pt_BR.json
@@ -463,6 +463,8 @@
 "label.dashboard": "Dashboard",
 "label.data.disk": "Disco de dados",
 "label.data.disk.offering": "Oferta de disco adicional",
+"label.data.pool": "Data pool",
+"label.data.pool.description": "\u00c9 necess\u00e1rio informar um data pool 
ao utilizar um Ceph pool com erasure code",
 "label.date": "Data",
 "label.day": "Dia",
 "label.day.of.month": "Dia do m\u00eas",
diff --git a/ui/src/components/view/DetailsTab.vue 
b/ui/src/components/view/DetailsTab.vue
index 3622f87e67d..bbabd8c801d 100644
--- a/ui/src/components/view/DetailsTab.vue
+++ b/ui/src/components/view/DetailsTab.vue
@@ -151,6 +151,13 @@
           <div>{{ $toLocaleDate(dataResource[item]) }}</div>
         </div>
       </a-list-item>
+      <a-list-item v-else-if="item === 'details' && $route.meta.name === 
'storagepool' && dataResource[item].rbd_default_data_pool">
+        <div>
+          <strong>{{ $t('label.data.pool') }}</strong>
+          <br/>
+          <div>{{ dataResource[item].rbd_default_data_pool }}</div>
+        </div>
+      </a-list-item>
     </template>
     <HostInfo :resource="dataResource" v-if="$route.meta.name === 'host' && 
'listHosts' in $store.getters.apis" />
     <DedicateData :resource="dataResource" v-if="dedicatedSectionActive" />
@@ -207,7 +214,7 @@ export default {
   },
   computed: {
     customDisplayItems () {
-      var items = ['ip4routes', 'ip6routes', 'privatemtu', 'publicmtu', 
'provider']
+      var items = ['ip4routes', 'ip6routes', 'privatemtu', 'publicmtu', 
'provider', 'details']
       if (this.$route.meta.name === 'webhookdeliveries') {
         items.push('startdate')
         items.push('enddate')
diff --git a/ui/src/config/section/infra/primaryStorages.js 
b/ui/src/config/section/infra/primaryStorages.js
index 826ffc7422b..1b0e5ef1634 100644
--- a/ui/src/config/section/infra/primaryStorages.js
+++ b/ui/src/config/section/infra/primaryStorages.js
@@ -35,7 +35,7 @@ export default {
     fields.push('zonename')
     return fields
   },
-  details: ['name', 'id', 'ipaddress', 'type', 'nfsmountopts', 'scope', 
'tags', 'path', 'provider', 'hypervisor', 'overprovisionfactor', 
'disksizetotal', 'disksizeallocated', 'disksizeused', 'capacityiops', 
'usediops', 'clustername', 'podname', 'zonename', 'created'],
+  details: ['name', 'id', 'ipaddress', 'type', 'details', 'nfsmountopts', 
'scope', 'tags', 'path', 'provider', 'hypervisor', 'overprovisionfactor', 
'disksizetotal', 'disksizeallocated', 'disksizeused', 'capacityiops', 
'usediops', 'clustername', 'podname', 'zonename', 'created'],
   related: [{
     name: 'volume',
     title: 'label.volumes',
diff --git a/ui/src/views/infra/AddPrimaryStorage.vue 
b/ui/src/views/infra/AddPrimaryStorage.vue
index 1420d7b6ff1..01532f3071b 100644
--- a/ui/src/views/infra/AddPrimaryStorage.vue
+++ b/ui/src/views/infra/AddPrimaryStorage.vue
@@ -370,6 +370,12 @@
           <a-form-item name="radospool" ref="radospool" 
:label="$t('label.rados.pool')">
             <a-input v-model:value="form.radospool" 
:placeholder="$t('label.rados.pool')"/>
           </a-form-item>
+          <a-form-item name="datapool" ref="datapool">
+            <template #label>
+              <tooltip-label :title="$t('label.data.pool')" 
:tooltip="$t('label.data.pool.description')"/>
+            </template>
+            <a-input v-model:value="form.datapool" 
:placeholder="$t('label.data.pool')"/>
+          </a-form-item>
           <a-form-item name="radosuser" ref="radosuser" 
:label="$t('label.rados.user')">
             <a-input v-model:value="form.radosuser" 
:placeholder="$t('label.rados.user')" />
           </a-form-item>
@@ -499,6 +505,10 @@ export default {
         powerflexGatewayUsername: [{ required: true, message: 
this.$t('label.required') }],
         powerflexGatewayPassword: [{ required: true, message: 
this.$t('label.required') }],
         powerflexStoragePool: [{ required: true, message: 
this.$t('label.required') }],
+        radosmonitor: [{ required: true, message: this.$t('label.required') }],
+        radospool: [{ required: true, message: this.$t('label.required') }],
+        radosuser: [{ required: true, message: this.$t('label.required') }],
+        radossecret: [{ required: true, message: this.$t('label.required') }],
         username: [{ required: true, message: this.$t('label.required') }],
         password: [{ required: true, message: this.$t('label.required') }],
         primeraURL: [{ required: true, message: this.$t('label.url') }],
@@ -845,6 +855,9 @@ export default {
           url = this.clvmURL(vg)
         } else if (values.protocol === 'RBD') {
           url = this.rbdURL(values.radosmonitor, values.radospool, 
values.radosuser, values.radossecret)
+          if (values.datapool) {
+            params['details[0].rbd_default_data_pool'] = values.datapool
+          }
         } else if (values.protocol === 'vmfs') {
           path = values.vCenterDataCenter
           if (path.substring(0, 1) !== '/') {
diff --git a/ui/src/views/infra/zone/ZoneWizardAddResources.vue 
b/ui/src/views/infra/zone/ZoneWizardAddResources.vue
index 00811ed3a10..76b90bd3661 100644
--- a/ui/src/views/infra/zone/ZoneWizardAddResources.vue
+++ b/ui/src/views/infra/zone/ZoneWizardAddResources.vue
@@ -469,7 +469,7 @@ export default {
           title: 'label.rados.monitor',
           key: 'primaryStorageRADOSMonitor',
           placeHolder: 'message.error.rados.monitor',
-          required: false,
+          required: true,
           display: {
             primaryStorageProtocol: ['rbd']
           }
@@ -478,6 +478,14 @@ export default {
           title: 'label.rados.pool',
           key: 'primaryStorageRADOSPool',
           placeHolder: 'message.error.rados.pool',
+          required: true,
+          display: {
+            primaryStorageProtocol: ['rbd']
+          }
+        },
+        {
+          title: 'label.data.pool',
+          key: 'primaryStorageDataPool',
           required: false,
           display: {
             primaryStorageProtocol: ['rbd']
@@ -487,7 +495,7 @@ export default {
           title: 'label.rados.user',
           key: 'primaryStorageRADOSUser',
           placeHolder: 'message.error.rados.user',
-          required: false,
+          required: true,
           display: {
             primaryStorageProtocol: ['rbd']
           }
@@ -496,7 +504,7 @@ export default {
           title: 'label.rados.secret',
           key: 'primaryStorageRADOSSecret',
           placeHolder: 'message.error.rados.secret',
-          required: false,
+          required: true,
           display: {
             primaryStorageProtocol: ['rbd']
           }
diff --git a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue 
b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue
index 01006cd0c72..a0d7c142a44 100644
--- a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue
+++ b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue
@@ -1486,6 +1486,10 @@ export default {
         const rbdpool = this.prefillContent?.primaryStorageRADOSPool || ''
         const rbdid = this.prefillContent?.primaryStorageRADOSUser || ''
         const rbdsecret = this.prefillContent?.primaryStorageRADOSSecret || ''
+
+        if (this.prefillContent?.primaryStorageDataPool) {
+          params['details[0].rbd_default_data_pool'] = 
this.prefillContent.primaryStorageDataPool
+        }
         url = this.rbdURL(rbdmonitor, rbdpool, rbdid, rbdsecret)
       } else if (protocol === 'Linstor') {
         url = this.linstorURL(server)


Reply via email to