From 7ccaa46b4a749896b2daabda390d8ddd3ae7743f Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Fri, 10 Apr 2015 14:55:54 +0000
Subject: [PATCH] 

---
 opendj-server-legacy/src/messages/org/opends/messages/backend.properties                      |    8 
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java        |    2 
 opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/Importer.java               |   96 ++--
 opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java                |   13 
 opendj-server-legacy/src/main/java/org/opends/server/extensions/DiskSpaceMonitor.java         |  585 ++++++++++++++++++++----------
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java         |   52 --
 opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/BackendImpl.java            |   65 +--
 opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java                  |   10 
 opendj-server-legacy/src/main/java/org/opends/server/api/DiskSpaceMonitorHandler.java         |   23 
 opendj-server-legacy/src/messages/org/opends/messages/core.properties                         |   10 
 opendj-server-legacy/src/main/java/org/opends/server/util/Platform.java                       |  163 ++++----
 opendj-server-legacy/src/messages/org/opends/messages/utility.properties                      |    3 
 opendj-server-legacy/src/main/java/org/opends/server/backends/persistit/PersistItStorage.java |   99 +---
 opendj-server-legacy/src/messages/org/opends/messages/jeb.properties                          |    6 
 14 files changed, 625 insertions(+), 510 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/api/DiskSpaceMonitorHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/api/DiskSpaceMonitorHandler.java
index 637879d..97de7e8 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/api/DiskSpaceMonitorHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/api/DiskSpaceMonitorHandler.java
@@ -27,7 +27,8 @@
 
 package org.opends.server.api;
 
-import org.opends.server.extensions.DiskSpaceMonitor;
+import java.io.File;
+
 
 /**
  * This interface defines the set of methods that must be implemented
@@ -40,22 +41,26 @@
   /**
    * Notifies that the registered "low" threshold have been reached.
    *
-   * @param monitor The DiskSpaceMonitor that detected this event.
+   * @param directory the directory for which the threshold has been triggered
+   * @param thresholdInBytes the threshold value in bytes
    */
-  void diskLowThresholdReached(DiskSpaceMonitor monitor);
+  void diskLowThresholdReached(File directory, long thresholdInBytes);
 
   /**
    * Notifies that the registered "full" threshold have been reached.
    *
-   * @param monitor The DiskSpaceMonitor that detected this event.
+   * @param directory the directory for which the threshold has been triggered
+   * @param thresholdInBytes the threshold value in bytes
    */
-  void diskFullThresholdReached(DiskSpaceMonitor monitor);
+  void diskFullThresholdReached(File directory, long thresholdInBytes);
 
   /**
-   * Notifies that the free disk space is now above both "low" and
-   * "full" thresholds.
+   * Notifies that the free disk space is now above both "low" and "full" thresholds.
    *
-   * @param monitor The DiskSpaceMonitor that detected this event.
+   * @param directory the directory for which the threshold has been triggeredTODO
+   *
+   * @param lowThresholdInBytes the low threshold value in bytes
+   * @param fullThresholdInBytes the full threshold value in bytes
    */
-  void diskSpaceRestored(DiskSpaceMonitor monitor);
+  void diskSpaceRestored(File directory, long lowThresholdInBytes, long fullThresholdInBytes);
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/BackendImpl.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/BackendImpl.java
index 639081b..a517e4e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/BackendImpl.java
@@ -27,7 +27,6 @@
 package org.opends.server.backends.jeb;
 
 import static com.sleepycat.je.EnvironmentConfig.*;
-
 import static org.opends.messages.BackendMessages.*;
 import static org.opends.messages.JebMessages.*;
 import static org.opends.server.backends.jeb.ConfigurableEnvironment.*;
@@ -58,6 +57,7 @@
 import org.opends.server.api.MonitorProvider;
 import org.opends.server.backends.RebuildConfig;
 import org.opends.server.backends.VerifyConfig;
+import org.opends.server.backends.pluggable.spi.StorageStatus;
 import org.opends.server.core.*;
 import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.types.*;
@@ -91,6 +91,7 @@
 
   private MonitorProvider<?> rootContainerMonitor;
   private DiskSpaceMonitor diskMonitor;
+  private StorageStatus storageStatus = StorageStatus.working();
 
   /**
    * The controls supported by this backend.
@@ -159,6 +160,7 @@
 
     this.cfg = cfg;
     baseDNs = this.cfg.getBaseDN().toArray(new DN[0]);
+    diskMonitor = serverContext.getDiskSpaceMonitor();
   }
 
   /** {@inheritDoc} */
@@ -206,11 +208,8 @@
     DirectoryServer.registerMonitorProvider(rootContainerMonitor);
 
     // Register as disk space monitor handler
-    diskMonitor = newDiskMonitor(cfg);
-    if (diskMonitor != null)
-    {
-      DirectoryServer.registerMonitorProvider(diskMonitor);
-    }
+    diskMonitor.registerMonitoredDirectory(getBackendID(), getDirectory(), cfg.getDiskLowThreshold(),
+        cfg.getDiskFullThreshold(), this);
 
     //Register as an AlertGenerator.
     DirectoryServer.registerAlertGenerator(this);
@@ -218,16 +217,10 @@
     cfg.addLocalDBChangeListener(this);
   }
 
-  private DiskSpaceMonitor newDiskMonitor(LocalDBBackendCfg cfg) throws ConfigException, InitializationException
+  private File getDirectory()
   {
     File parentDirectory = getFileForPath(cfg.getDBDirectory());
-    File backendDirectory =
-        new File(parentDirectory, cfg.getBackendId());
-    DiskSpaceMonitor dm = new DiskSpaceMonitor(getBackendID() + " backend",
-        backendDirectory, cfg.getDiskLowThreshold(), cfg.getDiskFullThreshold(),
-        5, TimeUnit.SECONDS, this);
-    dm.initializeMonitorProvider(null);
-    return dm;
+    return new File(parentDirectory, cfg.getBackendId());
   }
 
   /** {@inheritDoc} */
@@ -250,8 +243,7 @@
     }
 
     DirectoryServer.deregisterMonitorProvider(rootContainerMonitor);
-    DirectoryServer.deregisterMonitorProvider(diskMonitor);
-
+    diskMonitor.deregisterMonitoredDirectory(getDirectory(), this);
     // We presume the server will prevent more operations coming into this
     // backend, but there may be existing operations already in the
     // backend. We need to wait for them to finish.
@@ -717,7 +709,7 @@
       }
 
       final EnvironmentConfig envConfig = getEnvConfigForImport();
-      final Importer importer = new Importer(importConfig, cfg, envConfig);
+      final Importer importer = new Importer(importConfig, cfg, envConfig, serverContext);
       rootContainer = initializeRootContainer(envConfig);
       return importer.processImport(rootContainer);
     }
@@ -859,7 +851,7 @@
         envConfig = parseConfigEntry(cfg);
 
       }
-      final Importer importer = new Importer(rebuildConfig, cfg, envConfig);
+      final Importer importer = new Importer(rebuildConfig, cfg, envConfig, serverContext);
       importer.rebuildIndexes(rootContainer);
     }
     catch (ExecutionException execEx)
@@ -1002,10 +994,7 @@
         baseDNs = newBaseDNsArray;
       }
 
-      if (diskMonitor != null)
-      {
-        updateDiskMonitor(diskMonitor, newCfg);
-      }
+      updateDiskMonitor(diskMonitor, newCfg);
 
       // Put the new configuration in place.
       this.cfg = newCfg;
@@ -1020,8 +1009,8 @@
 
   private void updateDiskMonitor(DiskSpaceMonitor dm, LocalDBBackendCfg newCfg)
   {
-    dm.setFullThreshold(newCfg.getDiskFullThreshold());
-    dm.setLowThreshold(newCfg.getDiskLowThreshold());
+    diskMonitor.registerMonitoredDirectory(getBackendID(), getDirectory(), newCfg.getDiskLowThreshold(),
+        newCfg.getDiskFullThreshold(), this);
   }
 
   private void removeDeletedBaseDNs(SortedSet<DN> newBaseDNs) throws DirectoryException
@@ -1196,34 +1185,30 @@
 
   /** {@inheritDoc} */
   @Override
-  public void diskLowThresholdReached(DiskSpaceMonitor monitor) {
-    LocalizableMessage msg = ERR_JEB_DISK_LOW_THRESHOLD_REACHED.get(
-        monitor.getDirectory().getPath(), cfg.getBackendId(), monitor.getFreeSpace(),
-        Math.max(monitor.getLowThreshold(), monitor.getFullThreshold()));
-    DirectoryServer.sendAlertNotification(this, ALERT_TYPE_DISK_SPACE_LOW, msg);
+  public void diskLowThresholdReached(File directory, long thresholdInBytes) {
+    storageStatus = StorageStatus.lockedDown(
+        WARN_DISK_SPACE_LOW_THRESHOLD_CROSSED.get(directory.getFreeSpace(), directory.getAbsolutePath(),
+        thresholdInBytes, getBackendID()));
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskFullThresholdReached(DiskSpaceMonitor monitor) {
-    LocalizableMessage msg = ERR_JEB_DISK_FULL_THRESHOLD_REACHED.get(
-        monitor.getDirectory().getPath(), cfg.getBackendId(), monitor.getFreeSpace(),
-        Math.max(monitor.getLowThreshold(), monitor.getFullThreshold()));
-    DirectoryServer.sendAlertNotification(this, ALERT_TYPE_DISK_FULL, msg);
+  public void diskFullThresholdReached(File directory, long thresholdInBytes) {
+    storageStatus = StorageStatus.unusable(
+        WARN_DISK_SPACE_FULL_THRESHOLD_CROSSED.get(directory.getFreeSpace(), directory.getAbsolutePath(),
+        thresholdInBytes, getBackendID()));
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskSpaceRestored(DiskSpaceMonitor monitor) {
-    logger.error(NOTE_JEB_DISK_SPACE_RESTORED, monitor.getFreeSpace(),
-        monitor.getDirectory().getPath(), cfg.getBackendId(),
-        Math.max(monitor.getLowThreshold(), monitor.getFullThreshold()));
+  public void diskSpaceRestored(File directory, long lowThresholdInBytes, long fullThresholdInBytes) {
+    storageStatus = StorageStatus.working();
   }
 
   private void checkDiskSpace(Operation operation) throws DirectoryException
   {
-    if(diskMonitor.isFullThresholdReached() ||
-        (diskMonitor.isLowThresholdReached()
+    if(storageStatus.isUnusable() ||
+        (storageStatus.isLockedDown()
             && operation != null
             && !operation.getClientConnection().hasPrivilege(
                 Privilege.BYPASS_LOCKDOWN, operation)))
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/Importer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/Importer.java
index 1053bed..90868d3 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/Importer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/Importer.java
@@ -27,7 +27,6 @@
 package org.opends.server.backends.jeb;
 
 import static com.sleepycat.je.EnvironmentConfig.*;
-
 import static org.opends.messages.JebMessages.*;
 import static org.opends.server.admin.std.meta.LocalDBIndexCfgDefn.IndexType.*;
 import static org.opends.server.backends.jeb.IndexOutputBuffer.*;
@@ -84,7 +83,7 @@
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.i18n.LocalizableMessageDescriptor.Arg3;
+import org.forgerock.i18n.LocalizableMessageDescriptor.Arg2;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.config.server.ConfigException;
 import org.forgerock.opendj.ldap.ByteString;
@@ -98,6 +97,7 @@
 import org.opends.server.backends.RebuildConfig;
 import org.opends.server.backends.RebuildConfig.RebuildMode;
 import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.ServerContext;
 import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.DN;
@@ -162,6 +162,8 @@
   private static final int MIN_READ_AHEAD_CACHE_SIZE = 2 * KB;
   /** Small heap threshold used to give more memory to JVM to attempt OOM errors. */
   private static final int SMALL_HEAP_SIZE = 256 * MB;
+  /** Minimum memory needed for import */
+  private static final int MINIMUM_AVAILABLE_MEMORY = 32 * MB;
 
   /** The DN attribute type. */
   private static final AttributeType dnType;
@@ -267,6 +269,8 @@
   /** Number of phase one buffers. */
   private int phaseOneBufferCount;
 
+  private final DiskSpaceMonitor diskSpaceMonitor;
+
   static
   {
     AttributeType attrType = DirectoryServer.getAttributeType("dn");
@@ -286,6 +290,8 @@
    *          The local DB back-end configuration.
    * @param envConfig
    *          The JEB environment config.
+   * @param serverContext
+   *          The ServerContext for this Directory Server instance
    * @throws InitializationException
    *           If a problem occurs during initialization.
    * @throws JebException
@@ -293,14 +299,15 @@
    * @throws ConfigException
    *           If a problem occurs during initialization.
    */
-  public Importer(RebuildConfig rebuildConfig, LocalDBBackendCfg cfg,
-      EnvironmentConfig envConfig) throws InitializationException,
+  public Importer(RebuildConfig rebuildConfig, LocalDBBackendCfg cfg, EnvironmentConfig envConfig,
+      ServerContext serverContext) throws InitializationException,
       JebException, ConfigException
   {
     this.importConfiguration = null;
     this.backendConfiguration = cfg;
     this.tmpEnv = null;
     this.threadCount = 1;
+    this.diskSpaceMonitor = serverContext.getDiskSpaceMonitor();
     this.rebuildManager = new RebuildIndexManager(rebuildConfig, cfg);
     this.indexCount = rebuildManager.getIndexCount();
     this.clearedBackend = false;
@@ -327,6 +334,8 @@
    *          The local DB back-end configuration.
    * @param envConfig
    *          The JEB environment config.
+   * @param serverContext
+   *          The ServerContext for this Directory Server instance
    * @throws InitializationException
    *           If a problem occurs during initialization.
    * @throws ConfigException
@@ -334,13 +343,14 @@
    * @throws DatabaseException
    *           If an error occurred when opening the DB.
    */
-  public Importer(LDIFImportConfig importConfiguration,
-      LocalDBBackendCfg localDBBackendCfg, EnvironmentConfig envConfig)
+  public Importer(LDIFImportConfig importConfiguration, LocalDBBackendCfg localDBBackendCfg,
+      EnvironmentConfig envConfig, ServerContext serverContext)
       throws InitializationException, ConfigException, DatabaseException
   {
     this.rebuildManager = null;
     this.importConfiguration = importConfiguration;
     this.backendConfiguration = localDBBackendCfg;
+    this.diskSpaceMonitor = serverContext.getDiskSpaceMonitor();
 
     if (importConfiguration.getThreadCount() == 0)
     {
@@ -625,8 +635,8 @@
         configuredMemory = backendConfiguration.getDBCachePercent() * Runtime.getRuntime().maxMemory() / 100;
       }
 
-      // Round up to minimum of 16MB (e.g. unit tests only use 2% cache).
-      totalAvailableMemory = Math.max(Math.min(usableMemory, configuredMemory), 16 * MB);
+      // Round up to minimum of 32MB (e.g. unit tests only use a small cache).
+      totalAvailableMemory = Math.max(Math.min(usableMemory, configuredMemory), MINIMUM_AVAILABLE_MEMORY);
     }
     else
     {
@@ -860,14 +870,10 @@
     this.rootContainer = rootContainer;
     long startTime = System.currentTimeMillis();
 
-    DiskSpaceMonitor tmpMonitor = createDiskSpaceMonitor(tempDir, "backend index rebuild tmp directory");
-    tmpMonitor.initializeMonitorProvider(null);
-    DirectoryServer.registerMonitorProvider(tmpMonitor);
+    updateDiskMonitor(tempDir, "backend index rebuild tmp directory");
     File parentDirectory = getFileForPath(backendConfiguration.getDBDirectory());
     File backendDirectory = new File(parentDirectory, backendConfiguration.getBackendId());
-    DiskSpaceMonitor dbMonitor = createDiskSpaceMonitor(backendDirectory, "backend index rebuild DB directory");
-    dbMonitor.initializeMonitorProvider(null);
-    DirectoryServer.registerMonitorProvider(dbMonitor);
+    updateDiskMonitor(backendDirectory, "backend index rebuild DB directory");
 
     try
     {
@@ -879,10 +885,8 @@
     }
     finally
     {
-      DirectoryServer.deregisterMonitorProvider(tmpMonitor);
-      DirectoryServer.deregisterMonitorProvider(dbMonitor);
-      tmpMonitor.finalizeMonitorProvider();
-      dbMonitor.finalizeMonitorProvider();
+      diskSpaceMonitor.deregisterMonitoredDirectory(tempDir, this);
+      diskSpaceMonitor.deregisterMonitoredDirectory(backendDirectory, this);
     }
   }
 
@@ -908,8 +912,8 @@
       InterruptedException, ExecutionException
   {
     this.rootContainer = rootContainer;
-    DiskSpaceMonitor tmpMonitor = null;
-    DiskSpaceMonitor dbMonitor = null;
+    File parentDirectory = getFileForPath(backendConfiguration.getDBDirectory());
+    File backendDirectory = new File(parentDirectory, backendConfiguration.getBackendId());
     try {
       try
       {
@@ -921,14 +925,8 @@
         throw new InitializationException(message, ioe);
       }
 
-      tmpMonitor = createDiskSpaceMonitor(tempDir, "backend import tmp directory");
-      tmpMonitor.initializeMonitorProvider(null);
-      DirectoryServer.registerMonitorProvider(tmpMonitor);
-      File parentDirectory = getFileForPath(backendConfiguration.getDBDirectory());
-      File backendDirectory = new File(parentDirectory, backendConfiguration.getBackendId());
-      dbMonitor = createDiskSpaceMonitor(backendDirectory, "backend import DB directory");
-      dbMonitor.initializeMonitorProvider(null);
-      DirectoryServer.registerMonitorProvider(dbMonitor);
+      updateDiskMonitor(tempDir, "backend import tmp directory");
+      updateDiskMonitor(backendDirectory, "backend import DB directory");
 
       logger.info(NOTE_JEB_IMPORT_STARTING, DirectoryServer.getVersionString(),
               BUILD_ID, REVISION_NUMBER);
@@ -991,24 +989,15 @@
           // Do nothing.
         }
       }
-      if (tmpMonitor != null)
-      {
-        DirectoryServer.deregisterMonitorProvider(tmpMonitor);
-        tmpMonitor.finalizeMonitorProvider();
-      }
-      if (dbMonitor != null)
-      {
-        DirectoryServer.deregisterMonitorProvider(dbMonitor);
-        dbMonitor.finalizeMonitorProvider();
-      }
+      diskSpaceMonitor.deregisterMonitoredDirectory(tempDir, this);
+      diskSpaceMonitor.deregisterMonitoredDirectory(backendDirectory, this);
     }
   }
 
-  private DiskSpaceMonitor createDiskSpaceMonitor(File dir, String backendSuffix)
+  private void updateDiskMonitor(File dir, String backendSuffix)
   {
-    final LocalDBBackendCfg cfg = backendConfiguration;
-    return new DiskSpaceMonitor(cfg.getBackendId() + " " + backendSuffix, dir,
-        cfg.getDiskLowThreshold(), cfg.getDiskFullThreshold(), 5, TimeUnit.SECONDS, this);
+    diskSpaceMonitor.registerMonitoredDirectory(backendConfiguration.getBackendId() + " " + backendSuffix, dir,
+        backendConfiguration.getDiskLowThreshold(), backendConfiguration.getDiskFullThreshold(), this);
   }
 
   private void recursiveDelete(File dir)
@@ -3643,21 +3632,20 @@
     }
 
     @Override
-    public void diskLowThresholdReached(DiskSpaceMonitor monitor)
+    public void diskLowThresholdReached(File directory, long thresholdInBytes)
     {
-      diskFullThresholdReached(monitor);
+      diskFullThresholdReached(directory, thresholdInBytes);
     }
 
     @Override
-    public void diskFullThresholdReached(DiskSpaceMonitor monitor)
+    public void diskFullThresholdReached(File directory, long thresholdInBytes)
     {
       isCanceled = true;
-      logger.error(ERR_REBUILD_INDEX_LACK_DISK, monitor.getDirectory().getPath(),
-              monitor.getFreeSpace(), monitor.getLowThreshold());
+      logger.error(ERR_REBUILD_INDEX_LACK_DISK, directory.getAbsolutePath(), thresholdInBytes);
     }
 
     @Override
-    public void diskSpaceRestored(DiskSpaceMonitor monitor)
+    public void diskSpaceRestored(File directory, long lowThresholdInBytes, long fullThresholdInBytes)
     {
       // Do nothing
     }
@@ -4406,25 +4394,25 @@
 
   /** {@inheritDoc} */
   @Override
-  public void diskLowThresholdReached(DiskSpaceMonitor monitor)
+  public void diskLowThresholdReached(File directory, long thresholdInBytes)
   {
-    diskFullThresholdReached(monitor);
+    diskFullThresholdReached(directory, thresholdInBytes);
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskFullThresholdReached(DiskSpaceMonitor monitor)
+  public void diskFullThresholdReached(File directory, long thresholdInBytes)
   {
     isCanceled = true;
-    Arg3<Object, Number, Number> argMsg = !isPhaseOneDone
+    Arg2<Object, Number> argMsg = !isPhaseOneDone
         ? ERR_IMPORT_LDIF_LACK_DISK_PHASE_ONE
         : ERR_IMPORT_LDIF_LACK_DISK_PHASE_TWO;
-    logger.error(argMsg.get(monitor.getDirectory().getPath(), monitor.getFreeSpace(), monitor.getLowThreshold()));
+    logger.error(argMsg.get(directory.getAbsolutePath(), thresholdInBytes));
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskSpaceRestored(DiskSpaceMonitor monitor)
+  public void diskSpaceRestored(File directory, long lowThresholdInBytes, long fullThresholdInBytes)
   {
     // Do nothing.
   }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/persistit/PersistItStorage.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/persistit/PersistItStorage.java
index 8076ff5..98bc297 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/persistit/PersistItStorage.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/persistit/PersistItStorage.java
@@ -27,7 +27,6 @@
 
 import static com.persistit.Transaction.CommitPolicy.*;
 import static java.util.Arrays.*;
-
 import static org.opends.messages.BackendMessages.*;
 import static org.opends.messages.ConfigMessages.*;
 import static org.opends.messages.JebMessages.*;
@@ -37,10 +36,8 @@
 import java.io.File;
 import java.io.FilenameFilter;
 import java.util.HashMap;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.TimeUnit;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
@@ -50,7 +47,6 @@
 import org.forgerock.opendj.ldap.ByteString;
 import org.opends.server.admin.server.ConfigurationChangeListener;
 import org.opends.server.admin.std.server.PersistitBackendCfg;
-import org.opends.server.api.AlertGenerator;
 import org.opends.server.api.DiskSpaceMonitorHandler;
 import org.opends.server.backends.pluggable.spi.Cursor;
 import org.opends.server.backends.pluggable.spi.Importer;
@@ -66,7 +62,6 @@
 import org.opends.server.core.MemoryQuota;
 import org.opends.server.core.ServerContext;
 import org.opends.server.extensions.DiskSpaceMonitor;
-import org.opends.server.types.DN;
 import org.opends.server.types.FilePermission;
 
 import com.persistit.Configuration;
@@ -86,7 +81,7 @@
 /** PersistIt database implementation of the {@link Storage} engine. */
 @SuppressWarnings("javadoc")
 public final class PersistItStorage implements Storage, ConfigurationChangeListener<PersistitBackendCfg>,
-  DiskSpaceMonitorHandler, AlertGenerator
+  DiskSpaceMonitorHandler
 {
   private static final String VOLUME_NAME = "dj";
   /** The buffer / page size used by the PersistIt storage. */
@@ -505,6 +500,7 @@
   private PersistitBackendCfg config;
   private DiskSpaceMonitor diskMonitor;
   private MemoryQuota memQuota;
+  private StorageStatus storageStatus = StorageStatus.working();
 
   /**
    * Creates a new persistit storage with the provided configuration.
@@ -528,6 +524,7 @@
     final BufferPoolConfiguration bufferPoolCfg = getBufferPoolCfg();
     bufferPoolCfg.setMaximumCount(Integer.MAX_VALUE);
 
+    diskMonitor = serverContext.getDiskSpaceMonitor();
     memQuota = serverContext.getMemoryQuota();
     if (cfg.getDBCacheSize() > 0)
     {
@@ -568,8 +565,7 @@
       memQuota.releaseMemory(memQuota.memPercentToBytes(config.getDBCachePercent()));
     }
     config.removePersistitChangeListener(this);
-    DirectoryServer.deregisterMonitorProvider(diskMonitor);
-    DirectoryServer.deregisterAlertGenerator(this);
+    diskMonitor.deregisterMonitoredDirectory(getDirectory(), this);
   }
 
   private BufferPoolConfiguration getBufferPoolCfg()
@@ -598,11 +594,12 @@
     {
       throw new StorageRuntimeException(e);
     }
-    // Register as disk space monitor handler
-    diskMonitor = newDiskMonitor(config);
-    DirectoryServer.registerMonitorProvider(diskMonitor);
-    //Register as an AlertGenerator.
-    DirectoryServer.registerAlertGenerator(this);
+    diskMonitor.registerMonitoredDirectory(
+        config.getBackendId() + " backend",
+        getDirectory(),
+        config.getDiskLowThreshold(),
+        config.getDiskFullThreshold(),
+        this);
   }
 
   /** {@inheritDoc} */
@@ -968,9 +965,12 @@
 
         setDBDirPermissions(cfg, newBackendDirectory);
       }
-      diskMonitor.setFullThreshold(cfg.getDiskFullThreshold());
-      diskMonitor.setLowThreshold(cfg.getDiskLowThreshold());
-
+      diskMonitor.registerMonitoredDirectory(
+        config.getBackendId() + " backend",
+        getDirectory(),
+        cfg.getDiskLowThreshold(),
+        cfg.getDiskFullThreshold(),
+        this);
       config = cfg;
     }
     catch (Exception e)
@@ -1037,74 +1037,29 @@
   @Override
   public StorageStatus getStorageStatus()
   {
-    if (diskMonitor.isFullThresholdReached())
-    {
-      return StorageStatus.unusable(WARN_JEB_OUT_OF_DISK_SPACE.get());
-    }
-    if (diskMonitor.isLowThresholdReached())
-    {
-      return StorageStatus.lockedDown(WARN_JEB_OUT_OF_DISK_SPACE.get());
-    }
-    return StorageStatus.working();
+    return storageStatus;
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskFullThresholdReached(DiskSpaceMonitor monitor) {
-    LocalizableMessage msg = ERR_JEB_DISK_FULL_THRESHOLD_REACHED.get(
-        monitor.getDirectory().getPath(), config.getBackendId(), monitor.getFreeSpace(),
-        Math.max(monitor.getLowThreshold(), monitor.getFullThreshold()));
-    DirectoryServer.sendAlertNotification(this, ALERT_TYPE_DISK_FULL, msg);
+  public void diskFullThresholdReached(File directory, long thresholdInBytes) {
+    storageStatus = StorageStatus.unusable(
+        WARN_DISK_SPACE_FULL_THRESHOLD_CROSSED.get(directory.getFreeSpace(), directory.getAbsolutePath(),
+        thresholdInBytes, config.getBackendId()));
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskLowThresholdReached(DiskSpaceMonitor monitor) {
-    LocalizableMessage msg = ERR_JEB_DISK_LOW_THRESHOLD_REACHED.get(
-        monitor.getDirectory().getPath(), config.getBackendId(), monitor.getFreeSpace(),
-        Math.max(monitor.getLowThreshold(), monitor.getFullThreshold()));
-    DirectoryServer.sendAlertNotification(this, ALERT_TYPE_DISK_SPACE_LOW, msg);
+  public void diskLowThresholdReached(File directory, long thresholdInBytes) {
+    storageStatus = StorageStatus.lockedDown(
+        WARN_DISK_SPACE_LOW_THRESHOLD_CROSSED.get(directory.getFreeSpace(), directory.getAbsolutePath(),
+        thresholdInBytes, config.getBackendId()));
   }
 
   /** {@inheritDoc} */
   @Override
-  public void diskSpaceRestored(DiskSpaceMonitor monitor) {
-    logger.error(NOTE_JEB_DISK_SPACE_RESTORED, monitor.getFreeSpace(),
-        monitor.getDirectory().getPath(), config.getBackendId(),
-        Math.max(monitor.getLowThreshold(), monitor.getFullThreshold()));
-  }
-
-  private DiskSpaceMonitor newDiskMonitor(PersistitBackendCfg config) throws Exception
-  {
-    File parentDirectory = getFileForPath(config.getDBDirectory());
-    File backendDirectory = new File(parentDirectory, config.getBackendId());
-    DiskSpaceMonitor dm = new DiskSpaceMonitor(config.getBackendId() + " backend",
-        backendDirectory, config.getDiskLowThreshold(), config.getDiskFullThreshold(),
-        5, TimeUnit.SECONDS, this);
-    dm.initializeMonitorProvider(null);
-    return dm;
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public DN getComponentEntryDN() {
-    return config.dn();
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public String getClassName() {
-    return PersistItStorage.class.getName();
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public Map<String, String> getAlerts()
-  {
-    Map<String, String> alerts = new LinkedHashMap<String, String>();
-    alerts.put(ALERT_TYPE_DISK_SPACE_LOW, ALERT_DESCRIPTION_DISK_SPACE_LOW);
-    alerts.put(ALERT_TYPE_DISK_FULL, ALERT_DESCRIPTION_DISK_FULL);
-    return alerts;
+  public void diskSpaceRestored(File directory, long lowThresholdInBytes, long fullThresholdInBytes) {
+    storageStatus = StorageStatus.working();
   }
 }
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java
index 41bec03..4e984da 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java
@@ -84,7 +84,6 @@
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.i18n.LocalizableMessageDescriptor.Arg3;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.config.server.ConfigException;
 import org.forgerock.opendj.ldap.ByteSequence;
@@ -98,7 +97,6 @@
 import org.opends.server.admin.std.server.BackendIndexCfg;
 import org.opends.server.admin.std.server.PersistitBackendCfg;
 import org.opends.server.admin.std.server.PluggableBackendCfg;
-import org.opends.server.api.DiskSpaceMonitorHandler;
 import org.opends.server.backends.RebuildConfig;
 import org.opends.server.backends.RebuildConfig.RebuildMode;
 import org.opends.server.backends.persistit.PersistItStorage;
@@ -114,7 +112,6 @@
 import org.opends.server.backends.pluggable.spi.WriteableTransaction;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ServerContext;
-import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.DN;
 import org.opends.server.types.DirectoryException;
@@ -128,7 +125,7 @@
  * This class provides the engine that performs both importing of LDIF files and
  * the rebuilding of indexes.
  */
-final class Importer implements DiskSpaceMonitorHandler
+final class Importer
 {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
@@ -2781,7 +2778,7 @@
   /**
    * The rebuild index manager handles all rebuild index related processing.
    */
-  private class RebuildIndexManager extends ImportTask implements DiskSpaceMonitorHandler
+  private class RebuildIndexManager extends ImportTask
   {
 
     /** Rebuild index configuration. */
@@ -3402,26 +3399,6 @@
     {
       return this.totalEntries;
     }
-
-    @Override
-    public void diskLowThresholdReached(DiskSpaceMonitor monitor)
-    {
-      diskFullThresholdReached(monitor);
-    }
-
-    @Override
-    public void diskFullThresholdReached(DiskSpaceMonitor monitor)
-    {
-      isCanceled = true;
-      logger.error(ERR_REBUILD_INDEX_LACK_DISK, monitor.getDirectory().getPath(),
-              monitor.getFreeSpace(), monitor.getLowThreshold());
-    }
-
-    @Override
-    public void diskSpaceRestored(DiskSpaceMonitor monitor)
-    {
-      // Do nothing
-    }
   }
 
   /**
@@ -4035,29 +4012,4 @@
       }
     }
   }
-
-  /** {@inheritDoc} */
-  @Override
-  public void diskLowThresholdReached(DiskSpaceMonitor monitor)
-  {
-    diskFullThresholdReached(monitor);
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public void diskFullThresholdReached(DiskSpaceMonitor monitor)
-  {
-    isCanceled = true;
-    Arg3<Object, Number, Number> argMsg = !isPhaseOneDone
-        ? ERR_IMPORT_LDIF_LACK_DISK_PHASE_ONE
-        : ERR_IMPORT_LDIF_LACK_DISK_PHASE_TWO;
-    logger.error(argMsg.get(monitor.getDirectory().getPath(), monitor.getFreeSpace(), monitor.getLowThreshold()));
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public void diskSpaceRestored(DiskSpaceMonitor monitor)
-  {
-    // Do nothing.
-  }
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
index 9a0b462..937f721 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -136,6 +136,7 @@
 import org.opends.server.crypto.CryptoManagerImpl;
 import org.opends.server.crypto.CryptoManagerSync;
 import org.opends.server.extensions.ConfigFileHandler;
+import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.extensions.JMXAlertHandler;
 import org.opends.server.loggers.AccessLogger;
 import org.opends.server.loggers.DebugLogPublisher;
@@ -797,6 +798,9 @@
   /** The memory reservation system */
   private MemoryQuota memoryQuota;
 
+  /** The Disk Space Monitor */
+  private DiskSpaceMonitor diskSpaceMonitor;
+
   /**
    * The maximum size that internal buffers will be allowed to grow to until
    * they are trimmed.
@@ -898,6 +902,12 @@
     {
       return directoryServer.memoryQuota;
     }
+
+    @Override
+    public DiskSpaceMonitor getDiskSpaceMonitor()
+    {
+      return directoryServer.diskSpaceMonitor;
+    }
   }
 
 
@@ -930,6 +940,7 @@
     serverContext = new DirectoryServerContext();
     virtualAttributeConfigManager = new VirtualAttributeConfigManager(serverContext);
     memoryQuota = new MemoryQuota();
+    diskSpaceMonitor = new DiskSpaceMonitor();
   }
 
 
@@ -1470,6 +1481,8 @@
       // Determine whether or not we should start the connection handlers.
       boolean startConnectionHandlers = !environmentConfig.disableConnectionHandlers();
 
+      diskSpaceMonitor.startDiskSpaceMonitor();
+
       initializeSchema();
 
       // Allow internal plugins to be registered.
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
index 5756c7a..a27dde7 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ServerContext.java
@@ -26,6 +26,7 @@
 package org.opends.server.core;
 
 import org.forgerock.opendj.config.server.ServerManagementContext;
+import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.schema.SchemaUpdater;
 import org.opends.server.types.DirectoryEnvironmentConfig;
 import org.opends.server.types.Schema;
@@ -86,4 +87,13 @@
    * @return the memory quota system
    */
   MemoryQuota getMemoryQuota();
+
+  /**
+   * Returns the Disk Space Monitoring service, for checking free disk space.
+   * Configure a directory to be monitored and optionally get alerted when
+   * disk space transitions from low to full to back to normal.
+   *
+   * @return the Disk Space Monioring service
+   */
+  DiskSpaceMonitor getDiskSpaceMonitor();
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/DiskSpaceMonitor.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/DiskSpaceMonitor.java
index 5a88036..90ac02a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/DiskSpaceMonitor.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/DiskSpaceMonitor.java
@@ -28,23 +28,39 @@
 
 import static org.opends.messages.CoreMessages.*;
 import static org.opends.server.core.DirectoryServer.*;
+import static org.opends.server.util.ServerConstants.ALERT_DESCRIPTION_DISK_FULL;
+import static org.opends.server.util.ServerConstants.ALERT_DESCRIPTION_DISK_SPACE_LOW;
+import static org.opends.server.util.ServerConstants.ALERT_TYPE_DISK_FULL;
+import static org.opends.server.util.ServerConstants.ALERT_TYPE_DISK_SPACE_LOW;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.concurrent.TimeUnit;
 
+import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.config.server.ConfigException;
 import org.opends.server.admin.std.server.MonitorProviderCfg;
+import org.opends.server.api.AlertGenerator;
 import org.opends.server.api.AttributeSyntax;
 import org.opends.server.api.DiskSpaceMonitorHandler;
 import org.opends.server.api.MonitorProvider;
+import org.opends.server.api.ServerShutdownListener;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.Attributes;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
+import org.opends.server.util.Platform;
 
 /**
  * This class provides an application-wide disk space monitoring service.
@@ -56,243 +72,428 @@
  * have been reached, the handler will not be notified again until the
  * free space raises above the "low" threshold.
  */
-public class DiskSpaceMonitor extends MonitorProvider<MonitorProviderCfg>
-    implements Runnable
+public class DiskSpaceMonitor extends MonitorProvider<MonitorProviderCfg> implements Runnable, AlertGenerator,
+    ServerShutdownListener
 {
+  /**
+   * Helper class for each requestor for use with cn=monitor reporting and users of a spcific mountpoint.
+   */
+  private class MonitoredDirectory extends MonitorProvider<MonitorProviderCfg>
+  {
+    private volatile File directory;
+    private volatile long lowThreshold;
+    private volatile long fullThreshold;
+    private final DiskSpaceMonitorHandler handler;
+    private final String instanceName;
+    private final String baseName;
+    private int lastState;
+
+    private MonitoredDirectory(File directory, String instanceName, String baseName, DiskSpaceMonitorHandler handler)
+    {
+      this.directory = directory;
+      this.instanceName = instanceName;
+      this.baseName = baseName;
+      this.handler = handler;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getMonitorInstanceName() {
+      return instanceName + "," + "cn=" + baseName;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void initializeMonitorProvider(MonitorProviderCfg configuration)
+        throws ConfigException, InitializationException {
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public List<Attribute> getMonitorData() {
+      final List<Attribute> monitorAttrs = new ArrayList<Attribute>();
+      monitorAttrs.add(attr("disk-dir", getDefaultStringSyntax(), directory.getPath()));
+      monitorAttrs.add(attr("disk-free", getDefaultIntegerSyntax(), getFreeSpace()));
+      monitorAttrs.add(attr("disk-state", getDefaultStringSyntax(), getState()));
+      return monitorAttrs;
+    }
+
+    private File getDirectory() {
+      return directory;
+    }
+
+    private long getFreeSpace() {
+      return directory.getUsableSpace();
+    }
+
+    private long getFullThreshold() {
+      return fullThreshold;
+    }
+
+    private long getLowThreshold() {
+      return lowThreshold;
+    }
+
+    private void setFullThreshold(long fullThreshold) {
+      this.fullThreshold = fullThreshold;
+    }
+
+    private void setLowThreshold(long lowThreshold) {
+      this.lowThreshold = lowThreshold;
+    }
+
+    private Attribute attr(String name, AttributeSyntax<?> syntax, Object value)
+    {
+      AttributeType attrType = DirectoryServer.getDefaultAttributeType(name, syntax);
+      return Attributes.create(attrType, String.valueOf(value));
+    }
+
+    private String getState()
+    {
+      switch(lastState)
+      {
+      case NORMAL:
+        return "normal";
+      case LOW:
+        return "low";
+      case FULL:
+        return "full";
+      default:
+        return null;
+      }
+    }
+  }
+
+  /**
+   * Helper class for building temporary list of handlers to notify on threshold hits.
+   * One object per directory per state will hold all the handlers matching directory and state.
+   */
+  private class HandlerNotifier {
+    private File directory;
+    private int state;
+    /** printable list of handlers names, for reporting backend names in alert messages */
+    private final StringBuilder diskNames = new StringBuilder();
+    private final List<MonitoredDirectory> allHandlers = new ArrayList<MonitoredDirectory>();
+
+    private HandlerNotifier(File directory, int state)
+    {
+      this.directory = directory;
+      this.state = state;
+    }
+
+    private void notifyHandlers()
+    {
+      for (MonitoredDirectory mdElem : allHandlers)
+      {
+        switch (state)
+        {
+        case FULL:
+          mdElem.handler.diskFullThresholdReached(mdElem.getDirectory(), mdElem.getFullThreshold());
+          break;
+        case LOW:
+          mdElem.handler.diskLowThresholdReached(mdElem.getDirectory(), mdElem.getLowThreshold());
+          break;
+        case NORMAL:
+          mdElem.handler.diskSpaceRestored(mdElem.getDirectory(), mdElem.getLowThreshold(),
+              mdElem.getFullThreshold());
+          break;
+        }
+      }
+    }
+
+    private boolean isEmpty()
+    {
+      return allHandlers.size() == 0;
+    }
+
+    private void addHandler(MonitoredDirectory handler)
+    {
+      logger.trace("State change: %d -> %d", handler.lastState, state);
+      handler.lastState = state;
+      if (handler.handler != null)
+      {
+        allHandlers.add(handler);
+      }
+      appendName(diskNames, handler.instanceName);
+    }
+
+    private void appendName(StringBuilder strNames, String strVal)
+    {
+      if (strNames.length() > 0)
+      {
+        strNames.append(", ");
+      }
+      strNames.append(strVal);
+    }
+  }
+
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
   private static final int NORMAL = 0;
   private static final int LOW = 1;
   private static final int FULL = 2;
-
-  private volatile File directory;
-  private volatile long lowThreshold;
-  private volatile long fullThreshold;
-  private final DiskSpaceMonitorHandler handler;
-  private final int interval;
-  private final TimeUnit unit;
-  private final String instanceName;
-  private int lastState;
+  private static final String INSTANCENAME = "Disk Space Monitor";
+  private final HashMap<File, List<MonitoredDirectory>> monitoredDirs =
+      new HashMap<File, List<MonitoredDirectory>>();
 
   /**
-   * Constructs a new DiskSpaceMonitor that will notify the specified
-   * DiskSpaceMonitorHandler when the specified disk
-   * falls below the provided thresholds.
-   *
-   * @param instanceName A unique name for this monitor.
-   * @param directory The directory to monitor.
-   * @param lowThreshold The "low" threshold.
-   * @param fullThreshold   The "full" threshold.
-   * @param interval  The polling interval for checking free space.
-   * @param unit the time unit of the interval parameter.
-   * @param handler The handler to get notified when the provided thresholds are
-   *                reached or <code>null</code> if no notification is needed;
+   * Constructs a new DiskSpaceMonitor that will notify registered DiskSpaceMonitorHandler objects when filesystems
+   * on which configured directories reside, fall below the provided thresholds.
    */
-  public DiskSpaceMonitor(String instanceName, File directory,
-                          long lowThreshold,
-                          long fullThreshold, int interval, TimeUnit unit,
-                          DiskSpaceMonitorHandler handler) {
-    this.directory = directory;
-    this.lowThreshold = lowThreshold;
-    this.fullThreshold = fullThreshold;
-    this.interval = interval;
-    this.unit = unit;
-    this.handler = handler;
-    this.instanceName = instanceName+",cn=Disk Space Monitor";
-  }
-
-  /**
-   * Retrieves the directory currently being monitored.
-   *
-   * @return The directory currently being monitored.
-   */
-  public File getDirectory() {
-    return directory;
-  }
-
-  /**
-   * Sets the directory to monitor.
-   *
-   * @param directory The directory to monitor.
-   */
-  public void setDirectory(File directory) {
-    this.directory = directory;
-  }
-
-  /**
-   * Retrieves the currently "low" space threshold currently being enforced.
-   *
-   * @return The currently "low" space threshold currently being enforced.
-   */
-  public long getLowThreshold() {
-    return lowThreshold;
-  }
-
-  /**
-   * Sets the "low" space threshold to enforce.
-   *
-   * @param lowThreshold The "low" space threshold to enforce.
-   */
-  public void setLowThreshold(long lowThreshold) {
-    this.lowThreshold = lowThreshold;
-  }
-
-  /**
-   * Retrieves the currently full threshold currently being enforced.
-   *
-   * @return The currently full space threshold currently being enforced.
-   */
-  public long getFullThreshold() {
-    return fullThreshold;
-  }
-
-  /**
-   * Sets the full threshold to enforce.
-   *
-   * @param fullThreshold The full space threshold to enforce.
-   */
-  public void setFullThreshold(long fullThreshold) {
-    this.fullThreshold = fullThreshold;
-  }
-
-  /**
-   * Retrieves the free space currently on the disk.
-   *
-   * @return The free space currently on the disk.
-   */
-  public long getFreeSpace() {
-    return directory.getUsableSpace();
-  }
-
-  /**
-   * Indicates if the "full" threshold is reached.
-   *
-   * @return <code>true</code> if the free space is lower than the "full"
-   *         threshold or <code>false</code> otherwise.
-   */
-  public boolean isFullThresholdReached()
+  public DiskSpaceMonitor()
   {
-    return lastState >= FULL;
   }
 
   /**
-   * Indicates if the "low" threshold is reached.
-   *
-   * @return <code>true</code> if the free space is lower than the "low"
-   *         threshold or <code>false</code> otherwise.
+   * Starts periodic monitoring of all registered directories.
    */
-  public boolean isLowThresholdReached()
+  public void startDiskSpaceMonitor()
   {
-    return lastState >= LOW;
+    DirectoryServer.registerMonitorProvider(this);
+    DirectoryServer.registerShutdownListener(this);
+    scheduleUpdate(this, 0, 5, TimeUnit.SECONDS);
+  }
+
+  /**
+   * Registers or reconfigures a directory for monitoring.
+   * If possible, we will try to get and use the mountpoint where the directory resides and monitor it instead.
+   * If the directory is already registered for the same <code>handler</code>, simply change its configuration.
+   * @param instanceName A name for the handler, as used by cn=monitor
+   * @param directory The directory to monitor
+   * @param lowThresholdBytes Disk slow threshold expressed in bytes
+   * @param fullThresholdBytes Disk full threshold expressed in bytes
+   * @param handler The class requesting to be called when a transition in disk space occurs
+   */
+  public void registerMonitoredDirectory(String instanceName, File directory, long lowThresholdBytes,
+      long fullThresholdBytes, DiskSpaceMonitorHandler handler)
+  {
+    File fsMountPoint;
+    try
+    {
+      fsMountPoint = Platform.getFilesystem(directory);
+    }
+    catch (IOException ioe)
+    {
+      logger.warn(ERR_DISK_SPACE_GET_MOUNT_POINT, directory.getAbsolutePath(), ioe.getLocalizedMessage());
+      fsMountPoint = directory;
+    }
+    MonitoredDirectory newDSH = new MonitoredDirectory(directory, instanceName, INSTANCENAME, handler);
+    newDSH.setFullThreshold(fullThresholdBytes);
+    newDSH.setLowThreshold(lowThresholdBytes);
+
+    synchronized (monitoredDirs)
+    {
+      List<MonitoredDirectory> diskHelpers = monitoredDirs.get(fsMountPoint);
+      if (diskHelpers == null)
+      {
+        List<MonitoredDirectory> newList = new ArrayList<MonitoredDirectory>();
+        newList.add(newDSH);
+        monitoredDirs.put(fsMountPoint, newList);
+      }
+      else
+      {
+        for (MonitoredDirectory elem : diskHelpers)
+        {
+          if (elem.handler.equals(handler) && elem.getDirectory().equals(directory))
+          {
+            elem.setFullThreshold(fullThresholdBytes);
+            elem.setLowThreshold(lowThresholdBytes);
+            return;
+          }
+        }
+        diskHelpers.add(newDSH);
+      }
+      DirectoryServer.registerMonitorProvider(newDSH);
+    }
+  }
+
+  /**
+   * Removes a directory from the set of monitored directories.
+   *
+   * @param directory The directory to stop monitoring on
+   * @param handler The class that requested monitoring
+   */
+  public void deregisterMonitoredDirectory(File directory, DiskSpaceMonitorHandler handler)
+  {
+    synchronized (monitoredDirs)
+    {
+
+      List<MonitoredDirectory> directories = monitoredDirs.get(directory);
+      if (directories != null)
+      {
+        Iterator<MonitoredDirectory> itr = directories.iterator();
+        while (itr.hasNext())
+        {
+          MonitoredDirectory curDirectory = itr.next();
+          if (curDirectory.handler.equals(handler))
+          {
+            DirectoryServer.deregisterMonitorProvider(curDirectory);
+            itr.remove();
+          }
+        }
+        if (directories.isEmpty())
+        {
+          monitoredDirs.remove(directory);
+        }
+      }
+    }
   }
 
   /** {@inheritDoc} */
   @Override
   public void initializeMonitorProvider(MonitorProviderCfg configuration)
       throws ConfigException, InitializationException {
-    scheduleUpdate(this, 0, interval, unit);
+    // Not used...
   }
 
   /** {@inheritDoc} */
   @Override
   public String getMonitorInstanceName() {
-    return instanceName;
+    return INSTANCENAME;
   }
 
   /** {@inheritDoc} */
   @Override
   public List<Attribute> getMonitorData() {
-    final ArrayList<Attribute> monitorAttrs = new ArrayList<Attribute>();
-    monitorAttrs.add(attr("disk-dir", getDefaultStringSyntax(), directory.getPath()));
-    monitorAttrs.add(attr("disk-free", getDefaultIntegerSyntax(), getFreeSpace()));
-    monitorAttrs.add(attr("disk-state", getDefaultStringSyntax(), getState()));
-    return monitorAttrs;
+    return new ArrayList<Attribute>();
   }
 
-  private Attribute attr(String name, AttributeSyntax<?> syntax, Object value)
+  /** {@inheritDoc} */
+  @Override
+  public void run()
   {
-    AttributeType attrType = DirectoryServer.getDefaultAttributeType(name, syntax);
-    return Attributes.create(attrType, String.valueOf(value));
-  }
+    List<HandlerNotifier> diskFull = new ArrayList<HandlerNotifier>();
+    List<HandlerNotifier> diskLow = new ArrayList<HandlerNotifier>();
+    List<HandlerNotifier> diskRestored = new ArrayList<HandlerNotifier>();
 
-  private String getState()
-  {
-    switch(lastState)
+    synchronized (monitoredDirs)
     {
-    case NORMAL:
-      return "normal";
-    case LOW:
-      return "low";
-    case FULL:
-      return "full";
-    default:
-      return null;
+      for (Entry<File, List<MonitoredDirectory>> dirElem : monitoredDirs.entrySet())
+      {
+        File directory = dirElem.getKey();
+        HandlerNotifier diskFullClients = new HandlerNotifier(directory, FULL);
+        HandlerNotifier diskLowClients = new HandlerNotifier(directory, LOW);
+        HandlerNotifier diskRestoredClients = new HandlerNotifier(directory, NORMAL);
+        try
+        {
+          long lastFreeSpace = directory.getUsableSpace();
+          for (MonitoredDirectory handlerElem : dirElem.getValue())
+          {
+            if (lastFreeSpace < handlerElem.getFullThreshold() && handlerElem.lastState < FULL)
+            {
+              diskFullClients.addHandler(handlerElem);
+            }
+            else if (lastFreeSpace < handlerElem.getLowThreshold() && handlerElem.lastState < LOW)
+            {
+              diskLowClients.addHandler(handlerElem);
+            }
+            else if (handlerElem.lastState != NORMAL)
+            {
+              diskRestoredClients.addHandler(handlerElem);
+            }
+          }
+          addToList(diskFull, diskFullClients);
+          addToList(diskLow, diskLowClients);
+          addToList(diskRestored, diskRestoredClients);
+        }
+        catch(Exception e)
+        {
+          logger.error(ERR_DISK_SPACE_MONITOR_UPDATE_FAILED, directory, e);
+          logger.traceException(e);
+        }
+      }
+    }
+    // It is probably better to notify handlers outside of the synchronized section.
+    sendNotification(diskFull, FULL, ALERT_DESCRIPTION_DISK_FULL);
+    sendNotification(diskLow, LOW, ALERT_TYPE_DISK_SPACE_LOW);
+    sendNotification(diskRestored, NORMAL, null);
+  }
+
+  private void addToList(List<HandlerNotifier> hnList, HandlerNotifier notifier)
+  {
+    if (!notifier.isEmpty())
+    {
+      hnList.add(notifier);
+    }
+  }
+
+  private void sendNotification(List<HandlerNotifier> diskList, int state, String alert)
+  {
+    for (HandlerNotifier dirElem : diskList)
+    {
+      String dirPath = dirElem.directory.getAbsolutePath();
+      String handlerNames = dirElem.diskNames.toString();
+      long freeSpace = dirElem.directory.getFreeSpace();
+      if (state == FULL)
+      {
+        DirectoryServer.sendAlertNotification(this, alert,
+            ERR_DISK_SPACE_FULL_THRESHOLD_REACHED.get(dirPath, handlerNames, freeSpace));
+      }
+      else if (state == LOW)
+      {
+        DirectoryServer.sendAlertNotification(this, alert,
+            ERR_DISK_SPACE_LOW_THRESHOLD_REACHED.get(dirPath, handlerNames, freeSpace));
+      }
+      else
+      {
+        logger.error(NOTE_DISK_SPACE_RESTORED.get(freeSpace, dirPath));
+      }
+      dirElem.notifyHandlers();
     }
   }
 
   /** {@inheritDoc} */
   @Override
-  public void run() {
+  public DN getComponentEntryDN()
+  {
     try
     {
-      long lastFreeSpace = directory.getUsableSpace();
-
-      if(logger.isTraceEnabled())
-      {
-        logger.trace("Free space for %s: %d, " +
-            "low threshold: %d, full threshold: %d, state: %d",
-            directory.getPath(), lastFreeSpace, lowThreshold, fullThreshold,
-            lastState);
-      }
-
-      if(lastFreeSpace < fullThreshold)
-      {
-        if (lastState < FULL)
-        {
-          if(logger.isTraceEnabled())
-          {
-            logger.trace("State change: %d -> %d", lastState, FULL);
-          }
-
-          lastState = FULL;
-          if(handler != null)
-          {
-            handler.diskFullThresholdReached(this);
-          }
-        }
-      }
-      else if(lastFreeSpace < lowThreshold)
-      {
-        if (lastState < LOW)
-        {
-          if(logger.isTraceEnabled())
-          {
-            logger.trace("State change: %d -> %d", lastState, LOW);
-          }
-          lastState = LOW;
-          if(handler != null)
-          {
-            handler.diskLowThresholdReached(this);
-          }
-        }
-      }
-      else if (lastState != NORMAL)
-      {
-        if(logger.isTraceEnabled())
-        {
-          logger.trace("State change: %d -> %d", lastState, NORMAL);
-        }
-        lastState = NORMAL;
-        if(handler != null)
-        {
-          handler.diskSpaceRestored(this);
-        }
-      }
+      return DN.valueOf(INSTANCENAME);
     }
-    catch(Exception e)
+    catch (DirectoryException de)
     {
-      logger.error(ERR_DISK_SPACE_MONITOR_UPDATE_FAILED, directory.getPath(), e);
-      logger.traceException(e);
+      return DN.NULL_DN;
     }
   }
+
+  /** {@inheritDoc} */
+  @Override
+  public String getClassName()
+  {
+    return DiskSpaceMonitor.class.getName();
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Map<String, String> getAlerts()
+  {
+    Map<String, String> alerts = new LinkedHashMap<String, String>();
+    alerts.put(ALERT_TYPE_DISK_SPACE_LOW, ALERT_DESCRIPTION_DISK_SPACE_LOW);
+    alerts.put(ALERT_TYPE_DISK_FULL, ALERT_DESCRIPTION_DISK_FULL);
+    return alerts;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public String getShutdownListenerName()
+  {
+    return INSTANCENAME;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void processServerShutdown(LocalizableMessage reason)
+  {
+    synchronized (monitoredDirs)
+    {
+      for (Entry<File, List<MonitoredDirectory>> dirElem : monitoredDirs.entrySet())
+      {
+        for (MonitoredDirectory handlerElem : dirElem.getValue())
+        {
+          DirectoryServer.deregisterMonitorProvider(handlerElem);
+        }
+      }
+    }
+    DirectoryServer.deregisterMonitorProvider(this);
+  }
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/util/Platform.java b/opendj-server-legacy/src/main/java/org/opends/server/util/Platform.java
index be9bc43..abe7988 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/util/Platform.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/util/Platform.java
@@ -36,15 +36,20 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.List;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryPoolMXBean;
 import java.lang.management.MemoryUsage;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+
 import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.slf4j.LocalizedLogger;
+
 import static org.opends.messages.UtilityMessages.*;
 
 
@@ -108,8 +113,29 @@
     /** Constructors for each of the above classes. */
     private static Constructor<?> certKeyGenCons, X500NameCons;
 
+    /** Filesystem APIs */
+    private static Method FILESYSTEMS_GETSTORES;
+    private static Method FILESYSTEMS_PATHSGET;
+
+    private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+
     static
     {
+
+      try
+      {
+        // FileSystem and FileStores APIs were introduced in JDK 7.
+        FILESYSTEMS_PATHSGET = Class.forName("java.nio.file.Paths").getMethod("get", String.class, String[].class);
+        FILESYSTEMS_GETSTORES = Class.forName("java.nio.file.Files").getMethod(
+            "getFileStore", Class.forName("java.nio.file.Path"));
+      }
+      catch (Exception e)
+      {
+        FILESYSTEMS_GETSTORES = null;
+        FILESYSTEMS_PATHSGET = null;
+        logger.warn(WARN_UNABLE_TO_USE_FILESYSTEM_API.get());
+      }
+
       String x509pkg = pkgPrefix + ".x509";
       String certAndKeyGen;
       if (pkgPrefix.equals(IBM_SEC)
@@ -155,21 +181,7 @@
 
 
 
-    /**
-     * Delete the specified alias from the specified keystore.
-     *
-     * @param ks
-     *          The keystore to delete the alias from.
-     * @param ksPath
-     *          The path to the keystore.
-     * @param alias
-     *          The alias to use in the request generation.
-     * @param pwd
-     *          The keystore password to use.
-     * @throws KeyStoreException
-     *           If an error occurred deleting the alias.
-     */
-    public final void deleteAlias(KeyStore ks, String ksPath, String alias,
+    private final void deleteAlias(KeyStore ks, String ksPath, String alias,
         char[] pwd) throws KeyStoreException
     {
       try
@@ -193,28 +205,7 @@
 
 
 
-    /**
-     * Add the certificate in the specified path to the specified keystore,
-     * creating the keystore using the specified type and path if it the
-     * keystore doesn't exist.
-     *
-     * @param ks
-     *          The keystore to add the certificate to, may be null if it
-     *          doesn't exist.
-     * @param ksType
-     *          The type to use if the keystore is created.
-     * @param ksPath
-     *          The path to the keystore if it is created.
-     * @param alias
-     *          The alias to store the certificate under.
-     * @param pwd
-     *          The password to use in saving the certificate.
-     * @param certPath
-     *          The path to the file containing the certificate.
-     * @throws KeyStoreException
-     *           If an error occurred adding the certificate to the keystore.
-     */
-    public final void addCertificate(KeyStore ks, String ksType, String ksPath,
+    private final void addCertificate(KeyStore ks, String ksType, String ksPath,
         String alias, char[] pwd, String certPath) throws KeyStoreException
     {
       try
@@ -255,31 +246,7 @@
 
 
 
-    /**
-     * Generate a self-signed certificate using the specified alias, dn string
-     * and validity period. If the keystore does not exist, create it using the
-     * specified type and path.
-     *
-     * @param ks
-     *          The keystore to save the certificate in. May be null if it does
-     *          not exist.
-     * @param ksType
-     *          The keystore type to use if the keystore is created.
-     * @param ksPath
-     *          The path to the keystore if the keystore is created.
-     * @param alias
-     *          The alias to store the certificate under.
-     * @param pwd
-     *          The password to us in saving the certificate.
-     * @param dn
-     *          The dn string used as the certificate subject.
-     * @param validity
-     *          The validity of the certificate in days.
-     * @return The keystore that the self-signed certificate was stored in.
-     * @throws KeyStoreException
-     *           If the self-signed certificate cannot be generated.
-     */
-    public final KeyStore generateSelfSignedCertificate(KeyStore ks,
+    private final KeyStore generateSelfSignedCertificate(KeyStore ks,
         String ksType, String ksPath, String alias, char[] pwd, String dn,
         int validity) throws KeyStoreException
     {
@@ -330,19 +297,6 @@
     /**
      * Generate a x509 certificate from the input stream. Verification is done
      * only if it is self-signed.
-     *
-     * @param alias
-     *          The alias to save the certificate under.
-     * @param cf
-     *          The x509 certificate factory.
-     * @param ks
-     *          The keystore to add the certificate in.
-     * @param in
-     *          The input stream to read the certificate from.
-     * @throws KeyStoreException
-     *           If the alias exists already in the keystore, if the self-signed
-     *           certificate didn't verify, or the certificate could not be
-     *           stored.
      */
     private void trustedCert(String alias, CertificateFactory cf, KeyStore ks,
         InputStream in) throws KeyStoreException
@@ -369,10 +323,6 @@
 
     /**
      * Check that the issuer and subject DNs match.
-     *
-     * @param cert
-     *          The certificate to examine.
-     * @return {@code true} if the certificate is self-signed.
      */
     private boolean isSelfSigned(X509Certificate cert)
     {
@@ -391,14 +341,7 @@
 
 
 
-    /**
-     * Calculates the usable memory which could potentially be used by the
-     * application for caching objects.
-     *
-     * @return The usable memory which could potentially be used by the
-     *         application for caching objects.
-     */
-    public long getUsableMemoryForCaching()
+    private long getUsableMemoryForCaching()
     {
       long youngGenSize = 0;
       long oldGenSize = 0;
@@ -454,6 +397,40 @@
             .totalMemory())) * 40 / 100;
       }
     }
+
+    private File getFilesystem(File directory) throws IOException
+    {
+      if (FILESYSTEMS_GETSTORES != null)
+      {
+        try
+        {
+          Object dirFStore = FILESYSTEMS_GETSTORES.invoke(null,
+              FILESYSTEMS_PATHSGET.invoke(null, directory.getAbsolutePath(), new String[0]));
+          File parentDir = directory.getParentFile();
+          /*
+           * Since there is no concept of mount point in the APIs, iterate on all parents of
+           * the given directory until the FileSystem Store changes (hint of a different
+           * device, hence a mount point) or we get to root, which works too.
+           */
+          while (parentDir != null)
+          {
+            Object parentFStore = FILESYSTEMS_GETSTORES.invoke(null,
+                FILESYSTEMS_PATHSGET.invoke(null, parentDir.getAbsolutePath(), new String[0]));
+            if (!parentFStore.equals(dirFStore))
+            {
+              return directory;
+            }
+            directory = directory.getParentFile();
+            parentDir = directory.getParentFile();
+          }
+        }
+        catch (Exception e)
+        {
+          throw new IOException(e);
+        }
+      }
+      return directory;
+    }
   }
 
 
@@ -648,4 +625,16 @@
   {
     return IMPL.getUsableMemoryForCaching();
   }
+
+  /**
+   * Returns the filesystem on which the given directory resides by its mountpoint.
+   *
+   * @param directory the directory whose filesystem is required
+   * @return the filesystem on which the given directory resides
+   * @throws IOException The exception in case information on filesystem/storage cannot be found
+   */
+  public static File getFilesystem(File directory) throws IOException
+  {
+    return IMPL.getFilesystem(directory);
+  }
 }
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
index 2f717b5..3c4f0fb 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
@@ -1028,4 +1028,10 @@
  %d%% available
 ERR_VLV_BAD_ASSERTION_430=Unable to process the virtual list view request \
  because the target assertion could not be decoded as a valid value for the \
- '%s' attribute type
\ No newline at end of file
+ '%s' attribute type
+WARN_DISK_SPACE_LOW_THRESHOLD_CROSSED_431=Disk free space of %d bytes for directory %s is now below low threshold of \
+ %d bytes. Backend %s is now locked down and will no longer accept any operations from clients until sufficient disk \
+ space is restored
+WARN_DISK_SPACE_FULL_THRESHOLD_CROSSED_432=Disk free space of %d bytes for directory %s is now below disk low \
+ threshold of %d bytes. Backend %s is now offline and will no longer accept any operations until sufficient \
+ disk space is restored
\ No newline at end of file
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/core.properties b/opendj-server-legacy/src/messages/org/opends/messages/core.properties
index 5833a7d..eb040a0 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/core.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/core.properties
@@ -1429,4 +1429,12 @@
 ERR_PWPOLICY_REJECT_DUE_TO_UNKNOWN_VALIDATOR_LOG_747=The password for \
  user %s could not be validated because the password policy subentry %s is \
  referring to an unknown password validator (%s). Please make sure the password \
- policy subentry only refers to validators that exist on all replicas
\ No newline at end of file
+ policy subentry only refers to validators that exist on all replicas
+ERR_DISK_SPACE_GET_MOUNT_POINT_748=Could not get filesystem for directory %s: %s
+ERR_DISK_SPACE_LOW_THRESHOLD_REACHED_749=The disk containing directory %s used by %s is low on free space \
+ (%d bytes free). Write operations are only permitted by a user with the BYPASS_LOCKDOWN privilege until the free \
+ space rises above the threshold. Replication updates are still allowed
+ERR_DISK_SPACE_FULL_THRESHOLD_REACHED_750=The disk containing directory %s used by %s is full (%d bytes free). \
+ Write operations to the backend, replication updates included, will fail until the free space rises above the threshold
+NOTE_DISK_SPACE_RESTORED_751=The free space (%d bytes) on the disk containing directory %s is now above the \
+ threshold
\ No newline at end of file
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/jeb.properties b/opendj-server-legacy/src/messages/org/opends/messages/jeb.properties
index 120ba89..7850b7e 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/jeb.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/jeb.properties
@@ -374,14 +374,14 @@
  perform import phase 2 in a single batch. Some indexes will be imported using \
  several batches which may result in reduced performance
 ERR_IMPORT_LDIF_LACK_DISK_PHASE_ONE_222=The disk containing directory \
- %s is full (%d bytes free). After freeing more than %d bytes on the disk, \
+ %s is full. After freeing more than %d bytes on the disk, \
  import can continue in append and replace mode to load the rest of the \
  entries
 ERR_IMPORT_LDIF_LACK_DISK_PHASE_TWO_223=The disk containing directory \
- %s is full (%d bytes free). After freeing more than %d bytes on the disk, \
+ %s is full. After freeing more than %d bytes on the disk, \
  a rebuild of all the indexes is needed to complete the import
 ERR_REBUILD_INDEX_LACK_DISK_224=The disk containing directory \
- %s is full (%d bytes free). Rebuild index can not continue until the free \
+ %s is full. Rebuild index can not continue until the free \
  space rises above the threshold (%d bytes)
 INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED_225=%s index type is disabled for \
  the %s attribute
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/utility.properties b/opendj-server-legacy/src/messages/org/opends/messages/utility.properties
index 23f191a..b814f59 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/utility.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/utility.properties
@@ -571,4 +571,5 @@
 was received when reading its attributes: %s
 ERR_LDAP_CONN_BAD_INTEGER_302=Invalid integer number "%s". Please \
  enter a valid integer
-ERR_ARG_SUBCOMMAND_INVALID_303=Invalid subcommand
\ No newline at end of file
+ERR_ARG_SUBCOMMAND_INVALID_303=Invalid subcommand
+WARN_UNABLE_TO_USE_FILESYSTEM_API_304=Unable to gather information on Filesystem APIs, disk monitoring will be verbose
\ No newline at end of file
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java
index 93b0e75..f97d9a7 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/StateTest.java
@@ -47,6 +47,7 @@
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.MemoryQuota;
 import org.opends.server.core.ServerContext;
+import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.types.DN;
 import org.opends.server.types.DirectoryException;
 import org.testng.annotations.AfterMethod;
@@ -76,6 +77,7 @@
 
     ServerContext serverContext = mock(ServerContext.class);
     when(serverContext.getMemoryQuota()).thenReturn(new MemoryQuota());
+    when(serverContext.getDiskSpaceMonitor()).thenReturn(new DiskSpaceMonitor());
 
     storage = new PersistItStorage(createBackendCfg(), serverContext);
     org.opends.server.backends.pluggable.spi.Importer importer = storage.startImport();

--
Gitblit v1.10.0