mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
07.27.2016 0e7d33d36b47b90df873dda3c542bd72020bd682
OPENDJ-3417 Update lock management in BackendConfigManager to protect the registry of base Dns
2 files modified
145 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java 142 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java 3 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/BackendConfigManager.java
@@ -92,11 +92,6 @@
  private RootDSEBackend rootDSEBackend;
  /** Lock to protect reads of the backend maps. */
  private final ReadLock readLock;
  /** Lock to protect updates of the backends maps. */
  private final WriteLock writeLock;
  /**
   * Creates a new instance of this backend config manager.
   *
@@ -107,9 +102,6 @@
  {
    this.serverContext = serverContext;
    this.localBackendsRegistry = new BaseDnRegistry();
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    readLock = lock.readLock();
    writeLock = lock.writeLock();
  }
  /**
@@ -269,7 +261,8 @@
    backend.setBackendID(backendCfg.getBackendId());
    setLocalBackendWritabilityMode(backend, backendCfg);
    if (acquireSharedLock(backend, backendCfg.getBackendId(), ccr) && configureAndOpenBackend(backend, backendCfg, ccr))
    if (acquireSharedLock(backend, backendCfg.getBackendId(), ccr)
        && configureAndOpenBackend(backend, backendCfg, ccr))
    {
      registerBackend(backend, backendCfg, ccr);
    }
@@ -569,9 +562,6 @@
    ifNull(backend);
    String backendID = backend.getBackendID();
    ifNull(backendID);
    writeLock.lock();
    try
    {
      if (localBackends.containsKey(backendID))
      {
        LocalizableMessage message = ERR_REGISTER_BACKEND_ALREADY_EXISTS.get(backendID);
@@ -584,10 +574,6 @@
      backend.setBackendMonitor(monitor);
      registerMonitorProvider(monitor);
    }
    finally {
      writeLock.unlock();
    }
  }
  /**
   * Registers a local backend initialization listener.
@@ -635,9 +621,6 @@
  public void deregisterLocalBackend(LocalBackend<?> backend)
  {
    ifNull(backend);
    writeLock.lock();
    try
    {
      localBackends.remove(backend.getBackendID());
      LocalBackendMonitor monitor = backend.getBackendMonitor();
      if (monitor != null)
@@ -647,10 +630,6 @@
        backend.setBackendMonitor(null);
      }
    }
    finally {
      writeLock.unlock();
    }
  }
  @Override
  public boolean isConfigurationChangeAcceptable(
@@ -1241,6 +1220,10 @@
    private final TreeMap<DN, LocalBackend<?>> publicNamingContexts = new TreeMap<>();
    /** The set of public naming contexts, including sub-suffixes, registered with the server. */
    private final TreeMap<DN, LocalBackend<?>> allPublicNamingContexts = new TreeMap<>();
    /** Lock to protect reads of the maps. */
    private final ReadLock readLock;
    /** Lock to protect updates of the maps. */
    private final WriteLock writeLock;
    /**
     * Indicates whether this base DN registry is in test mode.
@@ -1263,6 +1246,20 @@
    List<LocalizableMessage> registerBaseDN(DN baseDN, LocalBackend<?> backend, boolean isPrivate)
        throws DirectoryException
    {
      writeLock.lock();
      try
      {
        return registerBaseDN0(baseDN, backend, isPrivate);
      }
      finally
      {
        writeLock.unlock();
      }
    }
    private List<LocalizableMessage> registerBaseDN0(DN baseDN, LocalBackend<?> backend, boolean isPrivate)
        throws DirectoryException
    {
      // Check to see if the base DN is already registered with the server.
      LocalBackend<?> existingBackend = baseDNs.get(baseDN);
      if (existingBackend != null)
@@ -1404,12 +1401,23 @@
    LocalBackend<?> getBackendWithBaseDN(DN entryDN)
    {
      readLock.lock();
      try
      {
      return baseDNs.get(entryDN);
    }
      finally
      {
        readLock.unlock();
      }
    }
    BackendAndName getBackendAndName(final DN entryDN)
    {
      readLock.lock();
      try
      {
      /*
       * Try to minimize the number of lookups in the map to find the backend containing the entry.
       * 1) If the DN contains many RDNs it is faster to iterate through the list of registered backends,
@@ -1448,10 +1456,18 @@
        return new BackendAndName(backend, matchedDN);
      }
    }
      finally
      {
        readLock.unlock();
      }
    }
    private LocalBackend<?> getSuperiorBackend(DN baseDN, LinkedList<DN> otherBaseDNs, String backendID)
        throws DirectoryException
    {
      readLock.lock();
      try
      {
      LocalBackend<?> superiorBackend = null;
      DN parentDN = baseDN.parent();
      while (parentDN != null)
@@ -1475,6 +1491,11 @@
      }
      return superiorBackend;
    }
      finally
      {
        readLock.unlock();
      }
    }
    /**
     * Deregisters a base DN with this registry.
@@ -1485,8 +1506,20 @@
     *         committed to the server
     * @throws DirectoryException if the base DN could not be deregistered
     */
     List<LocalizableMessage> deregisterBaseDN(DN baseDN)
           throws DirectoryException
     List<LocalizableMessage> deregisterBaseDN(DN baseDN) throws DirectoryException
     {
       writeLock.lock();
       try
       {
         return deregisterBaseDN0(baseDN);
       }
       finally
       {
         writeLock.unlock();
       }
     }
    List<LocalizableMessage> deregisterBaseDN0(DN baseDN) throws DirectoryException
    {
      ifNull(baseDN);
@@ -1618,6 +1651,9 @@
     */
    BaseDnRegistry copy()
    {
      readLock.lock();
      try
      {
      final BaseDnRegistry registry = new BaseDnRegistry(true);
      registry.baseDNs.putAll(baseDNs);
      registry.publicNamingContexts.putAll(publicNamingContexts);
@@ -1625,6 +1661,11 @@
      registry.privateNamingContexts.putAll(privateNamingContexts);
      return registry;
    }
      finally
      {
        readLock.unlock();
      }
    }
    /**
     * Creates a parameterized instance.
@@ -1635,16 +1676,9 @@
    private BaseDnRegistry(boolean testOnly)
    {
      this.testOnly = testOnly;
    }
    /**
     * Gets the mapping of registered base DNs to their associated backend.
     *
     * @return mapping from base DN to backend
     */
    Map<DN, LocalBackend<?>> getBaseDnMap()
    {
      return this.baseDNs;
      ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
      readLock = lock.readLock();
      writeLock = lock.writeLock();
    }
    /**
@@ -1655,8 +1689,16 @@
     */
    Map<DN, LocalBackend<?>> getPublicNamingContextsMap()
    {
      readLock.lock();
      try
      {
      return this.publicNamingContexts;
    }
      finally
      {
        readLock.unlock();
      }
    }
    /**
     * Gets the mapping of registered public naming contexts, including sub-suffixes,
@@ -1666,8 +1708,16 @@
     */
    Map<DN, LocalBackend<?>> getAllPublicNamingContextsMap()
    {
      readLock.lock();
      try
      {
      return this.allPublicNamingContexts;
    }
      finally
      {
        readLock.unlock();
      }
    }
    /**
     * Gets the mapping of registered private naming contexts to their
@@ -1677,8 +1727,16 @@
     */
    Map<DN, LocalBackend<?>> getPrivateNamingContextsMap()
    {
      readLock.lock();
      try
      {
      return this.privateNamingContexts;
    }
      finally
      {
        readLock.unlock();
      }
    }
    /**
     * Indicates whether the specified DN is contained in this registry as
@@ -1691,15 +1749,15 @@
     */
    boolean containsNamingContext(DN dn)
    {
      readLock.lock();
      try
      {
      return privateNamingContexts.containsKey(dn) || publicNamingContexts.containsKey(dn);
    }
    /** Clear and nullify this registry's internal state. */
    void clear() {
      baseDNs.clear();
      privateNamingContexts.clear();
      publicNamingContexts.clear();
      allPublicNamingContexts.clear();
      finally
      {
        readLock.unlock();
      }
    }
  }
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -207,9 +207,6 @@
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /** A lock to guarantee safe concurrent access to the registeredLocalBackends variable. */
  private static final Object registeredLocalBackendsLock = new Object();
  /**
   * Check if an OID is for a proxy authorization control.
   *