From 8c21d3ec1a6ab04e0011a7e988a3cdc8a8ae19ce Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 10 Dec 2020 13:51:44 +0100 Subject: [MountVmStore] Better handling of concurrent invocations --- src/main/java/org/openslx/satserver/util/Util.java | 13 ++++++++ .../openslx/taskmanager/tasks/MountVmStore.java | 37 ++++++++++++++++++---- 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main/java/org/openslx/satserver/util/Util.java b/src/main/java/org/openslx/satserver/util/Util.java index 55dc76b..262fd56 100644 --- a/src/main/java/org/openslx/satserver/util/Util.java +++ b/src/main/java/org/openslx/satserver/util/Util.java @@ -116,5 +116,18 @@ public class Util return defaultValue; } } + + /** + * Compare two strings for equality. + * null and "" are not considered equal. + */ + public static boolean strcmp(String a, String b) + { + if ( a == null && b == null ) + return true; + if ( a == null || b == null ) + return false; + return a.equals( b ); + } } diff --git a/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java b/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java index 2a46a10..d0530cc 100644 --- a/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java +++ b/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java @@ -1,7 +1,7 @@ package org.openslx.taskmanager.tasks; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import org.openslx.satserver.util.Constants; import org.openslx.satserver.util.Util; @@ -26,7 +26,7 @@ public class MountVmStore extends SystemCommandTask private Output status = new Output(); - private static AtomicBoolean isRunning = new AtomicBoolean(); + private static AtomicReference isRunning = new AtomicReference<>(); @Override protected boolean initTask() @@ -47,9 +47,19 @@ public class MountVmStore extends SystemCommandTask @Override protected String[] initCommandLine() { - if (!isRunning.compareAndSet( false, true )) { - status.addMessage("Another operation is already in progress."); - return null; + if ( !isRunning.compareAndSet( null, this ) ) { + MountVmStore current = isRunning.get(); + if ( current != null ) { + if ( current.equals( this ) ) { + // Exactly the same options - return other ID + status.existingTask = current.getId(); + status.addMessage( "Concurrent call with same options - see 'existingTask' field" ); + } else { + // Different options to existing, active task + status.addMessage( "Another operation is already in progress." ); + } + return null; + } } return new String[] { "/usr/bin/sudo", @@ -71,11 +81,25 @@ public class MountVmStore extends SystemCommandTask environment.put( "TM_MOUNT_OPTIONS", this.opts ); } } + + @Override + public boolean equals( Object obj ) + { + if ( !(obj instanceof MountVmStore) ) + return false; + MountVmStore o = (MountVmStore)obj; + return Util.strcmp( this.address, o.address ) + && Util.strcmp( this.type, o.type ) + && Util.strcmp( this.opts, o.opts ) + && Util.strcmp( this.username, o.username ) + && Util.strcmp( this.password, o.password ) + && this.localNfs == o.localNfs; + } @Override protected boolean processEnded( int exitCode ) { - isRunning.set( false ); + isRunning.set( null ); if ( exitCode != 0 ) status.addMessage( "Failed with exit code " + exitCode ); status.exitCode = exitCode; @@ -98,6 +122,7 @@ public class MountVmStore extends SystemCommandTask { public String messages = null; public int exitCode = -111; + public String existingTask; private void addMessage( String str ) { -- cgit v1.2.3-55-g7522