Skip to content

Commit ee38a87

Browse files
author
Eugenio Grosso
committed
flasharray: fall back to array capacity when pod has no quota
FlashArrayAdapter.getManagedStorageStats() returns null whenever the backing pod has no volumes (footprint == 0) and never reports anything other than the pod quota otherwise. A freshly-registered pool that sits on a pod without an explicit quota therefore shows disksizetotal=0, disksizeused=0 and the ClusterScopeStoragePoolAllocator refuses to allocate any volume against it (zero-capacity pool is skipped). The plugin is unusable until a pod quota is set manually on the array - which is not documented anywhere and not discoverable from the CloudStack side. Fix: fall back to the arrays total physical capacity (retrieved via GET /arrays?space=true) when the pod has no quota, or when the quota is zero. The used value falls back to the pod footprint, defaulting to 0 when absent. Only return null when no capacity value is obtainable at all, which now only happens if the array itself is unreachable. The math for usedBytes was also simplified: the previous form pod.getQuotaLimit() - (pod.getQuotaLimit() - pod.getFootprint()) is just pod.getFootprint() with an extra NPE risk when getQuotaLimit() is null.
1 parent be89e6f commit ee38a87

1 file changed

Lines changed: 31 additions & 3 deletions

File tree

  • plugins/storage/volume/flasharray/src/main/java/org/apache/cloudstack/storage/datastore/adapter/flasharray

plugins/storage/volume/flasharray/src/main/java/org/apache/cloudstack/storage/datastore/adapter/flasharray/FlashArrayAdapter.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,18 +453,46 @@ public void disconnect() {
453453
@Override
454454
public ProviderVolumeStorageStats getManagedStorageStats() {
455455
FlashArrayPod pod = getVolumeNamespace(this.pod);
456-
// just in case
457-
if (pod == null || pod.getFootprint() == 0) {
456+
if (pod == null) {
458457
return null;
459458
}
460459
Long capacityBytes = pod.getQuotaLimit();
461-
Long usedBytes = pod.getQuotaLimit() - (pod.getQuotaLimit() - pod.getFootprint());
460+
if (capacityBytes == null || capacityBytes == 0) {
461+
// Pod has no explicit quota set; report the array total physical
462+
// capacity so the CloudStack allocator has a real ceiling to plan
463+
// against rather than bailing out with a zero-capacity pool.
464+
capacityBytes = getArrayTotalCapacity();
465+
}
466+
if (capacityBytes == null || capacityBytes == 0) {
467+
return null;
468+
}
469+
Long usedBytes = pod.getFootprint();
470+
if (usedBytes == null) {
471+
usedBytes = 0L;
472+
}
462473
ProviderVolumeStorageStats stats = new ProviderVolumeStorageStats();
463474
stats.setCapacityInBytes(capacityBytes);
464475
stats.setActualUsedInBytes(usedBytes);
465476
return stats;
466477
}
467478

479+
private Long getArrayTotalCapacity() {
480+
try {
481+
FlashArrayList<Map<String, Object>> list = GET("/arrays?space=true",
482+
new TypeReference<FlashArrayList<Map<String, Object>>>() {
483+
});
484+
if (list != null && list.getItems() != null && !list.getItems().isEmpty()) {
485+
Object cap = list.getItems().get(0).get("capacity");
486+
if (cap instanceof Number) {
487+
return ((Number) cap).longValue();
488+
}
489+
}
490+
} catch (Exception e) {
491+
logger.warn("Could not retrieve array total capacity", e);
492+
}
493+
return null;
494+
}
495+
468496
@Override
469497
public ProviderVolumeStats getVolumeStats(ProviderAdapterContext context, ProviderAdapterDataObject dataObject) {
470498
ProviderVolume vol = getVolume(dataObject.getExternalName());

0 commit comments

Comments
 (0)