mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.20'
This commit is contained in:
commit
2c34f5e495
@ -202,10 +202,15 @@ public class SnapshotObject implements SnapshotInfo {
|
|||||||
@Override
|
@Override
|
||||||
public long getPhysicalSize() {
|
public long getPhysicalSize() {
|
||||||
long physicalSize = 0;
|
long physicalSize = 0;
|
||||||
SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findByStoreSnapshot(DataStoreRole.Image, store.getId(), snapshot.getId());
|
for (DataStoreRole role : List.of(DataStoreRole.Image, DataStoreRole.Primary)) {
|
||||||
|
logger.trace("Retrieving snapshot [{}] size from {} storage.", snapshot.getUuid(), role);
|
||||||
|
SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findByStoreSnapshot(role, store.getId(), snapshot.getId());
|
||||||
if (snapshotStore != null) {
|
if (snapshotStore != null) {
|
||||||
physicalSize = snapshotStore.getPhysicalSize();
|
return snapshotStore.getPhysicalSize();
|
||||||
}
|
}
|
||||||
|
logger.trace("Snapshot [{}] size not found on {} storage.", snapshot.getUuid(), role);
|
||||||
|
}
|
||||||
|
logger.warn("Snapshot [{}] reference not found in any storage. There may be an inconsistency on the database.", snapshot.getUuid());
|
||||||
return physicalSize;
|
return physicalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2025-08-05]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- getVolumeStats wasn't correctly working if multiple Linstor clusters/primary storages are used.
|
||||||
|
|
||||||
## [2025-07-01]
|
## [2025-07-01]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -137,7 +137,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
private HostDao _hostDao;
|
private HostDao _hostDao;
|
||||||
@Inject private VMTemplateDao _vmTemplateDao;
|
@Inject private VMTemplateDao _vmTemplateDao;
|
||||||
|
|
||||||
private long volumeStatsLastUpdate = 0L;
|
private final Map<String, Long> volumeStatsLastUpdate = new HashMap<>();
|
||||||
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
|
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
|
||||||
|
|
||||||
public LinstorPrimaryDataStoreDriverImpl()
|
public LinstorPrimaryDataStoreDriverImpl()
|
||||||
@ -1535,11 +1535,12 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the cache map containing current allocated size data.
|
* Updates the cache map containing current allocated size data.
|
||||||
* @param api Linstor Developers api object
|
* @param linstorAddr Linstor cluster api address
|
||||||
*/
|
*/
|
||||||
private void fillVolumeStatsCache(DevelopersApi api) {
|
private void fillVolumeStatsCache(String linstorAddr) {
|
||||||
|
final DevelopersApi api = LinstorUtil.getLinstorAPI(linstorAddr);
|
||||||
try {
|
try {
|
||||||
logger.trace("Start volume stats cache update");
|
logger.trace("Start volume stats cache update for " + linstorAddr);
|
||||||
List<ResourceWithVolumes> resources = api.viewResources(
|
List<ResourceWithVolumes> resources = api.viewResources(
|
||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
@ -1566,14 +1567,14 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeStats.clear();
|
volumeStats.keySet().removeIf(key -> key.startsWith(linstorAddr));
|
||||||
for (Map.Entry<String, Long> entry : allocSizeMap.entrySet()) {
|
for (Map.Entry<String, Long> entry : allocSizeMap.entrySet()) {
|
||||||
Long reserved = resSizeMap.getOrDefault(entry.getKey(), 0L);
|
Long reserved = resSizeMap.getOrDefault(entry.getKey(), 0L);
|
||||||
Pair<Long, Long> volStat = new Pair<>(entry.getValue(), reserved);
|
Pair<Long, Long> volStat = new Pair<>(entry.getValue(), reserved);
|
||||||
volumeStats.put(entry.getKey(), volStat);
|
volumeStats.put(linstorAddr + "/" + entry.getKey(), volStat);
|
||||||
}
|
}
|
||||||
volumeStatsLastUpdate = System.currentTimeMillis();
|
volumeStatsLastUpdate.put(linstorAddr, System.currentTimeMillis());
|
||||||
logger.trace("Done volume stats cache update: {}", volumeStats.size());
|
logger.debug(String.format("Done volume stats cache update for %s: %d", linstorAddr, volumeStats.size()));
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
logger.error("Unable to fetch Linstor resources: {}", e.getBestMessage());
|
logger.error("Unable to fetch Linstor resources: {}", e.getBestMessage());
|
||||||
}
|
}
|
||||||
@ -1581,14 +1582,19 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<Long, Long> getVolumeStats(StoragePool storagePool, String volumeId) {
|
public Pair<Long, Long> getVolumeStats(StoragePool storagePool, String volumeId) {
|
||||||
final DevelopersApi api = LinstorUtil.getLinstorAPI(storagePool.getHostAddress());
|
String linstorAddr = storagePool.getHostAddress();
|
||||||
synchronized (volumeStats) {
|
synchronized (volumeStats) {
|
||||||
long invalidateCacheTime = volumeStatsLastUpdate +
|
long invalidateCacheTime = volumeStatsLastUpdate.getOrDefault(storagePool.getHostAddress(), 0L) +
|
||||||
LinstorConfigurationManager.VolumeStatsCacheTime.value() * 1000;
|
LinstorConfigurationManager.VolumeStatsCacheTime.value() * 1000;
|
||||||
if (invalidateCacheTime < System.currentTimeMillis()) {
|
if (invalidateCacheTime < System.currentTimeMillis()) {
|
||||||
fillVolumeStatsCache(api);
|
fillVolumeStatsCache(storagePool.getHostAddress());
|
||||||
}
|
}
|
||||||
return volumeStats.get(LinstorUtil.RSC_PREFIX + volumeId);
|
String volumeKey = linstorAddr + "/" + LinstorUtil.RSC_PREFIX + volumeId;
|
||||||
|
Pair<Long, Long> sizePair = volumeStats.get(volumeKey);
|
||||||
|
if (sizePair == null) {
|
||||||
|
logger.warn(String.format("Volumestats for %s not found in cache", volumeKey));
|
||||||
|
}
|
||||||
|
return sizePair;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2211,7 +2211,11 @@ export default {
|
|||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
message = error.response.headers['x-description']
|
message = error.response.headers['x-description']
|
||||||
|
if (message.includes('is already in the database')) {
|
||||||
|
resolve()
|
||||||
|
} else {
|
||||||
reject(message)
|
reject(message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -2223,11 +2227,7 @@ export default {
|
|||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
message = error.response.headers['x-description']
|
message = error.response.headers['x-description']
|
||||||
if (message.includes('is already in the database')) {
|
|
||||||
resolve()
|
|
||||||
} else {
|
|
||||||
reject(message)
|
reject(message)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user