diff --git a/docs/TheBook/src/main/markdown/config-qos-engine.md b/docs/TheBook/src/main/markdown/config-qos-engine.md index a231930da3c..9d194b4bde6 100644 --- a/docs/TheBook/src/main/markdown/config-qos-engine.md +++ b/docs/TheBook/src/main/markdown/config-qos-engine.md @@ -1280,16 +1280,6 @@ be scheduled for scans. > > **Use the QoS transition to change existing disk+tape files to tape.** -### Changing pool tags - -If a pool's tags are used to determine replica distribution (based on the storage -unit definition of `onlyOneCopyPer`) and these are changed, QoS will not automatically -force the pool to be scanned immediately upon restart (it will just be -scheduled for a restart scan based on the defined grace period). - -> If it is desirable to rescan a pool's replicas immediately after its -> tags have been changed, this must be done manually (see above). - ### Troubleshooting operations Intervention to rectify qos handling should hopefully be needed infrequently; diff --git a/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpChangeHandler.java b/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpChangeHandler.java index c50d736fa15..27903b16572 100644 --- a/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpChangeHandler.java +++ b/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpChangeHandler.java @@ -61,6 +61,7 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; +import diskCacheV111.poolManager.CostModule; import diskCacheV111.poolManager.PoolSelectionUnit; import diskCacheV111.poolManager.PoolSelectionUnit.SelectionPool; import diskCacheV111.poolManager.PoolSelectionUnit.SelectionPoolGroup; @@ -69,9 +70,11 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING import diskCacheV111.poolManager.StorageUnitInfoExtractor; import diskCacheV111.pools.PoolV2Mode; import java.util.Collection; +import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; +import org.dcache.poolmanager.PoolInfo; import org.dcache.poolmanager.PoolMonitor; import org.dcache.qos.data.PoolQoSStatus; import org.dcache.qos.services.scanner.data.PoolFilter; @@ -114,6 +117,7 @@ public synchronized PoolOpDiff reloadAndScan(PoolMonitor newPoolMonitor) { diff.getPoolsAddedToPoolGroup().removeAll(p); diff.getPoolsRemovedFromPoolGroup().removeAll(p); diff.getModeChanged().remove(p); + diff.getTagsChanged().remove(p); }); PoolSelectionUnit currentPsu = newPoolMonitor.getPoolSelectionUnit(); @@ -153,6 +157,16 @@ public synchronized PoolOpDiff reloadAndScan(PoolMonitor newPoolMonitor) { LOGGER.trace("Rescanning the pool groups whose marker changed."); diff.getMarkerChanged().forEach(g -> scanPoolsOfModifiedPoolGroup(g, currentPsu)); + LOGGER.trace("Rescanning the pools with changed tags."); + diff.getTagsChanged().keySet().stream() + .map(currentPsu::getPool) + .forEach(p -> poolOperationMap.scan(p.getName(), + null, + null, + null, + p.getPoolMode(), + true)); + LOGGER.trace("Checking to see if previously uninitialized pools are now ready."); poolOperationMap.saveExcluded(); lastRefresh = System.currentTimeMillis(); @@ -221,6 +235,9 @@ private PoolOpDiff compare(PoolMonitor currentPoolMonitor, PoolMonitor nextPoolM LOGGER.trace("comparing pool mode"); comparePoolMode(diff, commonPools, nextPsu); + LOGGER.trace("comparing pool tags"); + comparePoolTags(diff, commonPools, currentPoolMonitor, nextPoolMonitor); + return diff; } @@ -307,6 +324,24 @@ private void comparePoolsInPoolGroups(PoolOpDiff diff, } } + private void comparePoolTags(PoolOpDiff diff, Set common, PoolMonitor current, + PoolMonitor next) { + CostModule currentCostModule = current.getCostModule(); + CostModule nextCostModule = next.getCostModule(); + + diff.getNewPools() + .forEach(p -> diff.getTagsChanged().put(p, getPoolTags(p, nextCostModule))); + + common.forEach(p -> { + Map newTags = getPoolTags(p, nextCostModule); + Map oldTags = getPoolTags(p, currentCostModule); + if (oldTags == null || (newTags != null + && !oldTags.equals(newTags))) { + diff.getTagsChanged().put(p, newTags); + } + }); + } + private Set compareStorageUnits(PoolOpDiff diff, PoolSelectionUnit currentPsu, PoolSelectionUnit nextPsu) { @@ -393,6 +428,14 @@ private Set comparePoolGroups(PoolOpDiff diff, return Sets.intersection(next, curr); } + private Map getPoolTags(String pool, CostModule costModule) { + PoolInfo poolInfo = costModule.getPoolInfo(pool); + if (poolInfo == null) { + return null; + } + return poolInfo.getTags(); + } + /** * Scans the "new" pool, also making sure all files have the sticky bit. */ diff --git a/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpDiff.java b/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpDiff.java index 4a17aa8d655..760ea446871 100644 --- a/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpDiff.java +++ b/modules/dcache-qos/src/main/java/org/dcache/qos/services/scanner/handlers/PoolOpDiff.java @@ -110,6 +110,12 @@ public final class PoolOpDiff { */ private final Map modeChanged = new HashMap<>(); + /* + * (pool, tags) + */ + private final Map> tagsChanged + = new HashMap<>(); + public Collection getConstraintsChanged() { return constraintsChanged; } @@ -154,6 +160,10 @@ public Multimap getPoolsRemovedFromPoolGroup() { return poolsRmved; } + public Map> getTagsChanged() { + return tagsChanged; + } + public Collection getUninitializedPools() { return uninitPools; } @@ -172,7 +182,7 @@ public boolean isEmpty() { && newUnits.isEmpty() && oldUnits.isEmpty() && poolsAdded.isEmpty() && poolsRmved.isEmpty() && unitsAdded.isEmpty() && unitsRmved.isEmpty() - && constraintsChanged.isEmpty() + && constraintsChanged.isEmpty() && tagsChanged.isEmpty() && modeChanged.isEmpty(); } @@ -189,12 +199,14 @@ public String toString() { "Units Added: %s\n" + "Units Removed: %s\n" + "Constraints changed: %s\n" + - "Mode changed: %s\n", + "Mode changed: %s\n" + + "Tags changed: %s\n", newPools, oldPools, uninitPools, newGroups, oldGroups, newUnits, oldUnits, poolsAdded, poolsRmved, unitsAdded, unitsRmved, - constraintsChanged, modeChanged); + constraintsChanged, modeChanged, + tagsChanged); } }