Damans227 commented on code in PR #14189:
URL: https://github.com/apache/cloudstack/pull/14189#discussion_r4168153283


##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java:
##########
@@ -700,40 +708,45 @@ public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, 
KVMStoragePool pool) {
      * adjust refcount
      */
     private int adjustStoragePoolRefCount(String uuid, int adjustment) {
-        final String mutexKey = storagePoolRefCounts.keySet().stream()
-                .filter(k -> k.equals(uuid))
-                .findFirst()
-                .orElse(uuid);
-        synchronized (mutexKey) {
-            // some access on the storagePoolRefCounts.key(mutexKey) element
-            int refCount = storagePoolRefCounts.computeIfAbsent(mutexKey, k -> 
0);
-            refCount += adjustment;
-            if (refCount < 1) {
-                storagePoolRefCounts.remove(mutexKey);
-            } else {
-                storagePoolRefCounts.put(mutexKey, refCount);
-            }
-            return refCount;
-        }
+        /*
+         * compute() is atomic for the key, so concurrent callers cannot lose 
an
+         * update. Returning null from the remapping function removes the 
entry,
+         * which keeps the map free of pools that are no longer in use.
+         */
+        Integer refCount = storagePoolRefCounts.compute(uuid, (key, count) -> {
+            int adjusted = (count == null ? 0 : count) + adjustment;
+            return adjusted < 1 ? null : adjusted;
+        });
+        return refCount == null ? 0 : refCount;
     }
     /**
      * Thread-safe increment storage pool usage refcount
      * @param uuid UUID of the storage pool to increment the count
      */
-    private void incStoragePoolRefCount(String uuid) {
+    protected void incStoragePoolRefCount(String uuid) {
         adjustStoragePoolRefCount(uuid, 1);
     }
     /**
      * Thread-safe decrement storage pool usage refcount for the given uuid 
and return if storage pool still in use.
      * @param uuid UUID of the storage pool to decrement the count
      * @return true if the storage pool is still used, else false.
      */
-    private boolean decStoragePoolRefCount(String uuid) {
+    protected boolean decStoragePoolRefCount(String uuid) {
         return adjustStoragePoolRefCount(uuid, -1) > 0;
     }
 
+    private static Object getStoragePoolLock(String uuid) {
+        return storagePoolLocks.computeIfAbsent(uuid, k -> new Object());
+    }
+
     @Override
     public KVMStoragePool createStoragePool(String name, String host, int 
port, String path, String userInfo, StoragePoolType type, Map<String, String> 
details, boolean isPrimaryStorage) {
+        synchronized (getStoragePoolLock(name)) {

Review Comment:
   if an unmount hangs, could this hold up every other pool on the host too? a 
create for the same pool waits here while still holding the manager wide lock



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to