Skip to content

Commit

Permalink
pool: Fix race condition in migration module
Browse files Browse the repository at this point in the history
Addresses an IllegalStateException in migration module.

The following exception can occur:

java.lang.IllegalStateException: Unexpected source pool list: Exactly one item was expected, but it contained 0
        at org.dcache.pool.migration.PoolListFilter.getSource(PoolListFilter.java:116) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.PoolListFilter.evaluate(PoolListFilter.java:126) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.PoolListFilter.isExcluded(PoolListFilter.java:101) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.PoolListFilter.getPools(PoolListFilter.java:76) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.Task.getPools(Task.java:195) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.Task.setLocations(Task.java:266) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.Task.access$000(Task.java:38) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.Task$1.success(Task.java:253) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.pool.migration.Task$1.success(Task.java:249) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.cells.AbstractMessageCallback.success(AbstractMessageCallback.java:31) ~[dcache-core-2.6.17.jar:2.6.17]
        at org.dcache.cells.CellStub$CellCallback.answerArrived(CellStub.java:416) ~[dcache-core-2.6.17.jar:2.6.17]
        at dmg.cells.nucleus.CellNucleus$CallbackTask.innerRun(CellNucleus.java:983) ~[cells-2.6.17.jar:2.6.17]
        at dmg.cells.nucleus.CellNucleus$AbstractNucleusTask.run(CellNucleus.java:941) ~[cells-2.6.17.jar:2.6.17]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_17]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_17]
        at java.lang.Thread.run(Thread.java:722) [na:1.7.0_17]

The problem occurs if migration module queries information about itself
from pool manager before pool manager has registered that information.
In that case a valid, but empty, reply from pool manager is received
and a pre-condition check in the migration module fails.

Target: trunk
Request: 2.7
Request: 2.6
Request: 2.2
Require-notes: yes
Require-book: no
Acked-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
Acked-by: Paul Millar <paul.millar@desy.de>
Patch: http://rb.dcache.org/r/6283/
  • Loading branch information
gbehrmann committed Dec 9, 2013
1 parent a6ec39a commit 641a644
Showing 1 changed file with 16 additions and 8 deletions.
Expand Up @@ -51,7 +51,7 @@ public PoolListFilter(RefreshablePoolList poolList,
@Override
public boolean isValid()
{
return _sourceList.isValid() && _poolList.isValid();
return _sourceList.isValid() && !_sourceList.getPools().isEmpty() && _poolList.isValid();
}

@Override
Expand All @@ -67,13 +67,17 @@ ImmutableList<PoolManagerPoolInformation> getPools()
if (!isValid()) {
return EMPTY_LIST;
}
PoolManagerPoolInformation source = getSource();
if (source == null) {
return EMPTY_LIST;
}

ImmutableList<PoolManagerPoolInformation> list = _poolList.getPools();
if (!list.equals(_cachedList)) {
ImmutableList.Builder<PoolManagerPoolInformation> filteredList =
ImmutableList.builder();
for (PoolManagerPoolInformation pool: list) {
if (!isExcluded(pool) && isIncluded(pool)) {
if (!isExcluded(source, pool) && isIncluded(source, pool)) {
filteredList.add(pool);
}
}
Expand All @@ -93,37 +97,41 @@ private boolean matchesAny(Collection<Pattern> patterns, String s)
return false;
}

private boolean isExcluded(PoolManagerPoolInformation pool)
private boolean isExcluded(PoolManagerPoolInformation source, PoolManagerPoolInformation pool)
{
if (matchesAny(_exclude, pool.getName())) {
return true;
}
return evaluate(_excludeWhen, pool);
return evaluate(_excludeWhen, source, pool);
}

private boolean isIncluded(PoolManagerPoolInformation pool)
private boolean isIncluded(PoolManagerPoolInformation source, PoolManagerPoolInformation pool)
{
if (!_include.isEmpty()) {
return matchesAny(_include, pool.getName());
}
return evaluate(_includeWhen, pool);
return evaluate(_includeWhen, source, pool);
}

private PoolManagerPoolInformation getSource()
{
List<PoolManagerPoolInformation> list = _sourceList.getPools();
if (list.size() != 1) {
if (list.isEmpty()) {
return null;
}
if (list.size() > 1) {
throw new IllegalStateException("Unexpected source pool list: Exactly one item was expected, but it contained " + list.size());
}
return list.get(0);
}

private boolean evaluate(Expression expression,
PoolManagerPoolInformation source,
PoolManagerPoolInformation pool)
{
SymbolTable symbols = new SymbolTable();
symbols.put(MigrationModule.CONSTANT_TARGET, pool);
symbols.put(MigrationModule.CONSTANT_SOURCE, getSource());
symbols.put(MigrationModule.CONSTANT_SOURCE, source);
return expression.evaluateBoolean(symbols);
}

Expand Down

0 comments on commit 641a644

Please sign in to comment.