From 1af0a1247d3e2d503a53723dd1d844c90c43ccc6 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Sat, 19 Sep 2026 08:56:47 +0000
Subject: [PATCH] [#993] Register an entry container's configuration listeners only once it has opened (#999)
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java | 41 +++++++++++++++++++++++++++--------------
1 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
index 917b230..d47e2db 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -467,15 +467,8 @@
this.dn2uri = new DN2URI(getIndexName(REFERRAL_TREE_NAME), this);
this.state = new State(getIndexName(STATE_TREE_NAME));
- config.addPluggableChangeListener(this);
-
attributeIndexCfgManager = new AttributeIndexCfgManager();
- config.addBackendIndexAddListener(attributeIndexCfgManager);
- config.addBackendIndexDeleteListener(attributeIndexCfgManager);
-
vlvIndexCfgManager = new VLVIndexCfgManager();
- config.addBackendVLVIndexAddListener(vlvIndexCfgManager);
- config.addBackendVLVIndexDeleteListener(vlvIndexCfgManager);
}
private CryptoSuite newCryptoSuite(boolean confidentiality)
@@ -533,13 +526,16 @@
CryptoSuite cryptoSuite = newCryptoSuite(indexCfg.isConfidentialityEnabled());
final AttributeIndex index = newAttributeIndex(indexCfg, cryptoSuite);
+ // Held before it is opened, because open() is what registers it as a listener of its own
+ // configuration and close() is what takes that off again: an index which fails while
+ // opening is one this container must still be able to close.
+ attrIndexMap.put(indexCfg.getAttribute(), index);
+ attrCryptoMap.put(indexCfg.getAttribute(), cryptoSuite);
index.open(txn, shouldCreate);
if(!index.isTrusted() && isNotEmpty)
{
logger.info(NOTE_INDEX_ADD_REQUIRES_REBUILD, index.getName());
}
- attrIndexMap.put(indexCfg.getAttribute(), index);
- attrCryptoMap.put(indexCfg.getAttribute(), cryptoSuite);
}
for (String idx : config.listBackendVLVIndexes())
@@ -547,20 +543,37 @@
BackendVLVIndexCfg vlvIndexCfg = config.getBackendVLVIndex(idx);
VLVIndex vlvIndex = new VLVIndex(vlvIndexCfg, state, storage, this, txn);
+ // Held before it is opened, for the reason given above, and here the window is wider still:
+ // a VLV index registers itself as a listener of its configuration from its constructor.
+ vlvIndexMap.put(vlvIndexCfg.getName().toLowerCase(), vlvIndex);
vlvIndex.open(txn, shouldCreate);
if(!vlvIndex.isTrusted() && isNotEmpty)
{
logger.info(NOTE_INDEX_ADD_REQUIRES_REBUILD, vlvIndex.getName());
}
-
- vlvIndexMap.put(vlvIndexCfg.getName().toLowerCase(), vlvIndex);
}
+
+ // Registered once everything they answer for is open, and never from the constructor: an
+ // entry container which fails to open is registered nowhere - RootContainer.openEntryContainer
+ // and BackendImpl.changeBaseDNTrees both let the failure through before anything holds it -
+ // so nothing would ever call the close() which takes these off again, and they would go on
+ // answering configuration changes for a backend which is not running. Nothing can reach this
+ // container in between either: open() is called before it is registered anywhere.
+ config.addPluggableChangeListener(this);
+ config.addBackendIndexAddListener(attributeIndexCfgManager);
+ config.addBackendIndexDeleteListener(attributeIndexCfgManager);
+ config.addBackendVLVIndexAddListener(vlvIndexCfgManager);
+ config.addBackendVLVIndexDeleteListener(vlvIndexCfgManager);
}
- catch (StorageRuntimeException de)
+ catch (Exception e)
{
- logger.traceException(de);
+ // Every failure, not the storage ones alone: open() is declared to throw ConfigException and
+ // does - an index type the attribute has no matching rule for, an index protecting both its
+ // keys and its values, a VLV filter or sort order which does not parse - and the indexes
+ // opened before it registered listeners of their own, which only close() takes back.
+ logger.traceException(e);
close();
- throw de;
+ throw e;
}
}
--
Gitblit v1.10.0