Skip to content

Commit 1fc1a5d

Browse files
rp-Locharla, Sandeep
authored andcommitted
linstor: use sparse/discard qemu-img convert on thin devices (apache#11787)
1 parent 77247b1 commit 1fc1a5d

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

plugins/storage/volume/linstor/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2025-10-03]
9+
10+
### Changed
11+
12+
- Revert qcow2 snapshot now use sparse/discard options to convert on thin devices.
13+
814
## [2025-08-05]
915

1016
### Fixed

plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.util.Optional;
4343
import java.util.stream.Collectors;
4444

45+
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
4546
import com.cloud.utils.Pair;
4647
import com.cloud.utils.exception.CloudRuntimeException;
4748
import org.apache.logging.log4j.Logger;
@@ -431,4 +432,37 @@ public static ResourceDefinition findResourceDefinition(DevelopersApi api, Strin
431432
public static boolean isRscDiskless(ResourceWithVolumes rsc) {
432433
return rsc.getFlags() != null && rsc.getFlags().contains(ApiConsts.FLAG_DISKLESS);
433434
}
435+
436+
/**
437+
* Checks if all diskful resource are on a zeroed block device.
438+
* @param pool Linstor pool to use
439+
* @param resName Linstor resource name
440+
* @return true if all resources are on a provider with zeroed blocks.
441+
*/
442+
public static boolean resourceSupportZeroBlocks(KVMStoragePool pool, String resName) {
443+
final DevelopersApi api = getLinstorAPI(pool.getSourceHost());
444+
try {
445+
List<ResourceWithVolumes> resWithVols = api.viewResources(
446+
Collections.emptyList(),
447+
Collections.singletonList(resName),
448+
Collections.emptyList(),
449+
Collections.emptyList(),
450+
null,
451+
null);
452+
453+
if (resWithVols != null) {
454+
return resWithVols.stream()
455+
.allMatch(res -> {
456+
Volume vol0 = res.getVolumes().get(0);
457+
return vol0 != null && (vol0.getProviderKind() == ProviderKind.LVM_THIN ||
458+
vol0.getProviderKind() == ProviderKind.ZFS ||
459+
vol0.getProviderKind() == ProviderKind.ZFS_THIN ||
460+
vol0.getProviderKind() == ProviderKind.DISKLESS);
461+
} );
462+
}
463+
} catch (ApiException apiExc) {
464+
s_logger.error(apiExc.getMessage());
465+
}
466+
return false;
467+
}
434468
}

0 commit comments

Comments
 (0)