This is an automated email from the ASF dual-hosted git repository.
Pearl1594 pushed a commit to branch clvm-enhancements
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/clvm-enhancements by this push:
new 124501d4ec5 allow storage browser to list lv in clvm, fix clvm shrink,
overprovisioning factor isnt used for clvm pools - so set it to 1 and prevented
display of provisioning type for clvm
124501d4ec5 is described below
commit 124501d4ec553c3c2b50cfdc515067295ab26b9d
Author: Pearl Dsilva <[email protected]>
AuthorDate: Fri Jun 12 11:15:51 2026 -0400
allow storage browser to list lv in clvm, fix clvm shrink, overprovisioning
factor isnt used for clvm pools - so set it to 1 and prevented display of
provisioning type for clvm
---
.../storage/motion/AncientDataMotionStrategy.java | 4 ++
.../motion/StorageSystemDataMotionStrategy.java | 10 ++--
.../kvm/resource/LibvirtComputingResource.java | 67 +++++++++++++++++++++-
.../kvm/storage/KVMStorageProcessor.java | 6 +-
.../api/query/dao/StoragePoolJoinDaoImpl.java | 13 ++++-
.../com/cloud/api/query/dao/VolumeJoinDaoImpl.java | 7 ++-
.../com/cloud/storage/VolumeApiServiceImpl.java | 2 +-
7 files changed, 96 insertions(+), 13 deletions(-)
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 c5713845e73..95362f44b13 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
@@ -76,6 +76,7 @@ import com.cloud.storage.ScopeType;
import com.cloud.storage.Snapshot.Type;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.StorageManager;
+import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VolumeVO;
@@ -609,6 +610,9 @@ public class AncientDataMotionStrategy implements
DataMotionStrategy {
volumeVo.setPoolId(destPool.getId());
volumeVo.setPoolType(destPool.getPoolType());
volumeVo.setLastPoolId(oldPoolId);
+ if (destPool.getPoolType() == StoragePoolType.CLVM) {
+ volumeVo.setFormat(ImageFormat.RAW);
+ }
// 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/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
index ffe7e2d89e6..2c791d05980 100644
---
a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
+++
b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
@@ -2496,12 +2496,13 @@ public class StorageSystemDataMotionStrategy implements
DataMotionStrategy {
if (success) {
VolumeVO volumeVO =
_volumeDao.findById(destVolumeInfo.getId());
- volumeVO.setFormat(ImageFormat.QCOW2);
+ StoragePoolVO srcPoolVO =
_storagePoolDao.findById(srcVolumeInfo.getPoolId());
+ StoragePoolVO destPoolVO =
_storagePoolDao.findById(destVolumeInfo.getPoolId());
+ volumeVO.setFormat(destPoolVO != null &&
destPoolVO.getPoolType() == StoragePoolType.CLVM
+ ? ImageFormat.RAW : ImageFormat.QCOW2);
volumeVO.setLastId(srcVolumeInfo.getId());
if (Objects.equals(srcVolumeInfo.getDiskOfferingId(),
destVolumeInfo.getDiskOfferingId())) {
- StoragePoolVO srcPoolVO =
_storagePoolDao.findById(srcVolumeInfo.getPoolId());
- StoragePoolVO destPoolVO =
_storagePoolDao.findById(destVolumeInfo.getPoolId());
if (srcPoolVO != null && destPoolVO != null &&
((srcPoolVO.isShared() && destPoolVO.isLocal()) ||
(srcPoolVO.isLocal() && destPoolVO.isShared()))) {
Long offeringId =
getSuitableDiskOfferingForVolumeOnPool(volumeVO, destPoolVO);
@@ -2512,9 +2513,6 @@ public class StorageSystemDataMotionStrategy implements
DataMotionStrategy {
}
_volumeDao.update(volumeVO.getId(), volumeVO);
-
- StoragePoolVO srcPoolVO =
_storagePoolDao.findById(srcVolumeInfo.getPoolId());
- StoragePoolVO destPoolVO =
_storagePoolDao.findById(destVolumeInfo.getPoolId());
if (destPoolVO != null &&
ClvmPoolManager.isClvmPoolType(destPoolVO.getPoolType())
&& (srcPoolVO == null || srcPoolVO.getId() !=
destPoolVO.getId())) {
sendClvmLockCommand(destHost.getId(), destPoolVO,
destVolumeInfo,
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 00d6c10300d..29e54b12f52 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
@@ -79,6 +79,7 @@ import org.apache.cloudstack.command.ReconcileCommandService;
import org.apache.cloudstack.command.ReconcileCommandUtils;
import
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.gpu.GpuDevice;
+import
org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsAnswer;
import
org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsCommand;
import org.apache.cloudstack.storage.configdrive.ConfigDrive;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
@@ -228,6 +229,7 @@ import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer;
+import com.cloud.storage.clvm.ClvmPoolManager;
import com.cloud.storage.Volume;
import com.cloud.storage.resource.StorageSubsystemCommandHandler;
import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
@@ -5735,10 +5737,73 @@ public class LibvirtComputingResource extends
ServerResourceBase implements Serv
public Answer listFilesAtPath(ListDataStoreObjectsCommand command) {
DataStoreTO store = command.getStore();
- KVMStoragePool storagePool =
storagePoolManager.getStoragePool(StoragePoolType.NetworkFilesystem,
store.getUuid());
+ StoragePoolType poolType = StoragePoolType.NetworkFilesystem;
+ if (store instanceof PrimaryDataStoreTO) {
+ poolType = ((PrimaryDataStoreTO) store).getPoolType();
+ }
+ KVMStoragePool storagePool =
storagePoolManager.getStoragePool(poolType, store.getUuid());
+ if (ClvmPoolManager.isClvmPoolType(poolType)) {
+ return listLvmVolumes(storagePool.getLocalPath(),
command.getStartIndex(), command.getPageSize());
+ }
return listFilesAtPath(storagePool.getLocalPath(), command.getPath(),
command.getStartIndex(), command.getPageSize());
}
+ private Answer listLvmVolumes(String localPath, int startIndex, int
pageSize) {
+ String vgName = localPath;
+ if (vgName.startsWith("/")) {
+ String[] parts = vgName.split("/");
+ for (int i = parts.length - 1; i >= 0; i--) {
+ if (!parts[i].isEmpty()) {
+ vgName = parts[i];
+ break;
+ }
+ }
+ }
+
+ Script lvs = new Script("lvs", 10000, logger);
+ lvs.add("--noheadings");
+ lvs.add("--nosuffix");
+ lvs.add("-o", "lv_name,lv_size");
+ lvs.add("--units", "b");
+ lvs.add(vgName);
+ AllLinesParser parser = new AllLinesParser();
+ String result = lvs.execute(parser);
+
+ List<String> names = new ArrayList<>();
+ List<String> paths = new ArrayList<>();
+ List<String> absPaths = new ArrayList<>();
+ List<Boolean> isDirs = new ArrayList<>();
+ List<Long> sizes = new ArrayList<>();
+ List<Long> lastModified = new ArrayList<>();
+
+ if (result != null) {
+ logger.warn("lvs listing failed for VG {}: {}", vgName, result);
+ return new ListDataStoreObjectsAnswer(false, 0, names, paths,
absPaths, isDirs, sizes, lastModified);
+ }
+
+ List<String[]> entries = new ArrayList<>();
+ for (String line : parser.getLines().split("\n")) {
+ String trimmed = line.trim();
+ if (trimmed.isEmpty()) continue;
+ String[] cols = trimmed.split("\\s+");
+ if (cols.length >= 2) entries.add(cols);
+ }
+
+ int count = entries.size();
+ for (int i = startIndex; i < startIndex + pageSize && i < count; i++) {
+ String lvName = entries.get(i)[0];
+ long size = 0;
+ try { size = Long.parseLong(entries.get(i)[1]); } catch
(NumberFormatException ignored) {}
+ names.add(lvName);
+ paths.add("/" + lvName);
+ absPaths.add("/dev/" + vgName + "/" + lvName);
+ isDirs.add(false);
+ sizes.add(size);
+ lastModified.add(0L);
+ }
+ return new ListDataStoreObjectsAnswer(true, count, names, paths,
absPaths, isDirs, sizes, lastModified);
+ }
+
public boolean addNetworkRules(final String vmName, final String vmId,
final String guestIP, final String guestIP6, final String sig, final String
seq, final String mac, final String rules, final String vif, final String
brname,
final String secIps) {
if (!canBridgeFirewall) {
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 499116f0bad..4a77f7e9e19 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
@@ -410,7 +410,8 @@ public class KVMStorageProcessor implements
StorageProcessor {
StoragePoolType.RBD,
StoragePoolType.PowerFlex,
StoragePoolType.Linstor,
-
StoragePoolType.FiberChannel).contains(primaryPool.getType())) {
+ StoragePoolType.FiberChannel,
+ StoragePoolType.CLVM).contains(primaryPool.getType())) {
newTemplate.setFormat(ImageFormat.RAW);
} else {
newTemplate.setFormat(ImageFormat.QCOW2);
@@ -3413,7 +3414,8 @@ public class KVMStorageProcessor implements
StorageProcessor {
StoragePoolType.RBD,
StoragePoolType.PowerFlex,
StoragePoolType.Linstor,
- StoragePoolType.FiberChannel).contains(poolType)) {
+ StoragePoolType.FiberChannel,
+ StoragePoolType.CLVM).contains(poolType)) {
return ImageFormat.RAW;
} else {
return ImageFormat.QCOW2;
diff --git
a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
index a9d5b726b86..6505f9287ff 100644
--- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
@@ -23,6 +23,7 @@ import java.util.Map;
import javax.inject.Inject;
+import com.cloud.storage.clvm.ClvmPoolManager;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.response.StoragePoolResponse;
@@ -183,7 +184,11 @@ public class StoragePoolJoinDaoImpl extends
GenericDaoBase<StoragePoolJoinVO, Lo
poolResponse.setTags(pool.getTag());
poolResponse.setStorageAccessGroups(pool.getStorageAccessGroup());
poolResponse.setIsTagARule(pool.getIsTagARule());
-
poolResponse.setOverProvisionFactor(Double.toString(CapacityManager.StorageOverprovisioningFactor.valueIn(pool.getId())));
+ if (ClvmPoolManager.isClvmPoolType(pool.getPoolType())) {
+ poolResponse.setOverProvisionFactor(String.valueOf(1));
+ } else {
+
poolResponse.setOverProvisionFactor(Double.toString(CapacityManager.StorageOverprovisioningFactor.valueIn(pool.getId())));
+ }
poolResponse.setManaged(storagePool.isManaged());
Map<String, String> details =
ApiDBUtils.getResourceDetails(pool.getId(),
ResourceTag.ResourceObjectType.Storage);
poolResponse.setDetails(details);
@@ -274,7 +279,11 @@ public class StoragePoolJoinDaoImpl extends
GenericDaoBase<StoragePoolJoinVO, Lo
}
}
-
poolResponse.setOverProvisionFactor(Double.toString(CapacityManager.StorageOverprovisioningFactor.valueIn(pool.getId())));
+ if (ClvmPoolManager.isClvmPoolType(pool.getPoolType())) {
+ poolResponse.setOverProvisionFactor(String.valueOf(1));
+ } else {
+
poolResponse.setOverProvisionFactor(Double.toString(CapacityManager.StorageOverprovisioningFactor.valueIn(pool.getId())));
+ }
// TODO: StatsCollector does not persist data
StorageStats stats = ApiDBUtils.getStoragePoolStatistics(pool.getId());
diff --git
a/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
index a92427ca19f..94d06b2ed6b 100644
--- a/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
@@ -22,6 +22,7 @@ import java.util.List;
import javax.inject.Inject;
+import com.cloud.storage.clvm.ClvmPoolManager;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
@@ -134,7 +135,11 @@ public class VolumeJoinDaoImpl extends
GenericDaoBaseWithTagInformation<VolumeJo
}
if (volume.getProvisioningType() != null) {
-
volResponse.setProvisioningType(volume.getProvisioningType().toString());
+ Long poolId = volume.getPoolId();
+ StoragePoolVO poolVO = primaryDataStoreDao.findById(poolId);
+ if (poolVO == null ||
!ClvmPoolManager.isClvmPoolType(poolVO.getPoolType())) {
+
volResponse.setProvisioningType(volume.getProvisioningType().toString());
+ }
}
// Show the virtual size of the volume
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index 0a78e77b5fa..83bf6b6962a 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -2607,7 +2607,7 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
}
if (volume != null &&
ImageFormat.QCOW2.equals(volume.getFormat()) &&
!Volume.State.Allocated.equals(volume.getState()) &&
- !Arrays.asList(StoragePoolType.StorPool,
StoragePoolType.Linstor).contains(volume.getPoolType())) {
+ !Arrays.asList(StoragePoolType.StorPool,
StoragePoolType.Linstor,
StoragePoolType.CLVM_NG).contains(volume.getPoolType())) {
String message = "Unable to shrink volumes of type QCOW2";
logger.warn(message);
throw new InvalidParameterValueException(message);