diff --git a/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/CopyAdjuster.java b/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/CopyAdjuster.java index 24bd37fc2e6..b7141457926 100644 --- a/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/CopyAdjuster.java +++ b/modules/dcache-qos/src/main/java/org/dcache/qos/services/adjuster/adjusters/CopyAdjuster.java @@ -136,7 +136,8 @@ private synchronized void createTask(PoolManagerPoolInformation targetInfo, Stri false, // compute checksum on update; should not happen false, // force copy even if pool is not readable true, // maintain atime - 1); // only one copy per task + 1, // only one copy per task + true); // wait for new targets if necessary createTask(taskParameters, source); diff --git a/modules/dcache-resilience/src/main/java/org/dcache/resilience/handlers/FileOperationHandler.java b/modules/dcache-resilience/src/main/java/org/dcache/resilience/handlers/FileOperationHandler.java index b01a37d55e9..7f0aafdbeb5 100644 --- a/modules/dcache-resilience/src/main/java/org/dcache/resilience/handlers/FileOperationHandler.java +++ b/modules/dcache-resilience/src/main/java/org/dcache/resilience/handlers/FileOperationHandler.java @@ -380,7 +380,8 @@ public Task handleMakeOneCopy(FileAttributes attributes) { false, // compute checksum on update; should not happen false, // force copy even if pool not readable true, // maintain atime - 1); + 1, // only one copy per task + true); // wait for new targets if necessary Task task = new Task(taskParameters, completionHandler, source, pnfsId, ReplicaState.CACHED, ONLINE_STICKY_RECORD, diff --git a/modules/dcache/src/main/java/org/dcache/pool/migration/Job.java b/modules/dcache/src/main/java/org/dcache/pool/migration/Job.java index d71307743f3..0043e17feb7 100644 --- a/modules/dcache/src/main/java/org/dcache/pool/migration/Job.java +++ b/modules/dcache/src/main/java/org/dcache/pool/migration/Job.java @@ -109,7 +109,7 @@ public Job(MigrationContext context, JobDefinition definition) { context.getExecutor(), definition.selectionStrategy, definition.poolList, definition.isEager, definition.isMetaOnly, definition.computeChecksumOnUpdate, definition.forceSourceMode, - definition.maintainAtime, definition.replicas); + definition.maintainAtime, definition.replicas, definition.waitForTargets); _pinPrefix = context.getPinManagerStub().getDestinationPath().getDestinationAddress() .getCellName(); diff --git a/modules/dcache/src/main/java/org/dcache/pool/migration/JobDefinition.java b/modules/dcache/src/main/java/org/dcache/pool/migration/JobDefinition.java index f7ede7f078c..c8ab4bfa5be 100644 --- a/modules/dcache/src/main/java/org/dcache/pool/migration/JobDefinition.java +++ b/modules/dcache/src/main/java/org/dcache/pool/migration/JobDefinition.java @@ -103,6 +103,12 @@ public class JobDefinition { */ public final int replicas; + /** + * Whether to wait for targets to become available to satisfy number of replicas. + */ + public final boolean waitForTargets; + + public JobDefinition(Predicate filter, CacheEntryMode sourceMode, CacheEntryMode targetMode, @@ -120,7 +126,8 @@ public JobDefinition(Predicate filter, boolean maintainAtime, Expression pauseWhen, Expression stopWhen, - boolean forceSourceMode) { + boolean forceSourceMode, + boolean waitForTargets) { this.filter = filter; this.sourceMode = sourceMode; this.targetMode = targetMode; @@ -139,5 +146,6 @@ public JobDefinition(Predicate filter, this.pauseWhen = pauseWhen; this.stopWhen = stopWhen; this.forceSourceMode = forceSourceMode; + this.waitForTargets = waitForTargets; } } diff --git a/modules/dcache/src/main/java/org/dcache/pool/migration/MigrationModule.java b/modules/dcache/src/main/java/org/dcache/pool/migration/MigrationModule.java index db419a5cdea..556f3177b99 100644 --- a/modules/dcache/src/main/java/org/dcache/pool/migration/MigrationModule.java +++ b/modules/dcache/src/main/java/org/dcache/pool/migration/MigrationModule.java @@ -537,6 +537,16 @@ public class MigrationCopyCommand implements Callable { usage = "Enables the transfer of files from a disabled pool.") boolean forceSourceMode; + @Option(name = "target-deficit-mode", metaVar = "tdmode", + values = { "wait", "limit" }, + category = "Transfer options", + usage = "Behaviour when requested replicas exceeds available targets:\n" + + "wait:\n" + + " wait for new targets to become available.\n" + + "limit:\n" + + " limit the number of replicas to that of the currently-available targets.\n") + String targetDeficitMode = "wait"; + @Argument(metaVar = "target", required = false, usage = "Required unless -target=pgroup is supplied, in which case we" + @@ -838,7 +848,8 @@ public String call() throws IllegalArgumentException { maintainAtime, createLifetimePredicate(pauseWhen), createLifetimePredicate(stopWhen), - forceSourceMode); + forceSourceMode, + targetDeficitMode.equals("wait")); if (definition.targetMode.state == CacheEntryMode.State.DELETE || definition.targetMode.state == CacheEntryMode.State.REMOVABLE) { diff --git a/modules/dcache/src/main/java/org/dcache/pool/migration/TaskParameters.java b/modules/dcache/src/main/java/org/dcache/pool/migration/TaskParameters.java index f9c9748c01a..ab48ddf2f35 100644 --- a/modules/dcache/src/main/java/org/dcache/pool/migration/TaskParameters.java +++ b/modules/dcache/src/main/java/org/dcache/pool/migration/TaskParameters.java @@ -88,11 +88,16 @@ public class TaskParameters { */ public final int replicas; + /** + * Whether to wait for targets to become available to satisfy number of replicas. + */ + public final boolean waitForTargets; + public TaskParameters(CellStub pool, CellStub pnfs, CellStub pinManager, ScheduledExecutorService executor, PoolSelectionStrategy selectionStrategy, RefreshablePoolList poolList, boolean isEager, boolean isMetaOnly, boolean computeChecksumOnUpdate, boolean forceSourceMode, - boolean maintainAtime, int replicas) { + boolean maintainAtime, int replicas, boolean waitForTargets) { this.pool = pool; this.pnfs = pnfs; this.pinManager = pinManager; @@ -105,5 +110,6 @@ public TaskParameters(CellStub pool, CellStub pnfs, CellStub pinManager, this.forceSourceMode = forceSourceMode; this.maintainAtime = maintainAtime; this.replicas = replicas; + this.waitForTargets = waitForTargets; } }