From 7486ef2bb077feb489a55db86707d96e69d12265 Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 30 Jul 2010 12:44:12 +0000
Subject: [PATCH] Implements a disk space thresholds feature, preventing the server from crashing or exiting of disks full.
---
opends/src/server/org/opends/server/backends/jeb/BackendImpl.java | 110 +++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 90 insertions(+), 20 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
index 3ccd2e0..3ba2210 100644
--- a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -45,9 +45,10 @@
import com.sleepycat.je.EnvironmentFailureException;
import java.util.logging.Level;
+
+import org.opends.server.api.DiskSpaceMonitorHandler;
import org.opends.server.backends.jeb.importLDIF.*;
import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
-import org.opends.server.admin.std.server.MonitorProviderCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.MonitorProvider;
import org.opends.server.api.AlertGenerator;
@@ -58,6 +59,7 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
+import org.opends.server.extensions.DiskSpaceMonitor;
import org.opends.server.util.LDIFException;
import org.opends.server.util.RuntimeInformation;
import org.opends.server.util.Validator;
@@ -82,7 +84,8 @@
*/
public class BackendImpl
extends Backend
- implements ConfigurationChangeListener<LocalDBBackendCfg>, AlertGenerator
+ implements ConfigurationChangeListener<LocalDBBackendCfg>, AlertGenerator,
+ DiskSpaceMonitorHandler
{
/**
* The tracer object for the debug logger.
@@ -118,16 +121,13 @@
private final AtomicInteger threadWriteCount = new AtomicInteger(0);
/**
- * A list of monitor providers created for this backend instance.
- */
- private ArrayList<MonitorProvider<?>> monitorProviders =
- new ArrayList<MonitorProvider<?>>();
-
- /**
* The base DNs defined for this backend instance.
*/
private DN[] baseDNs;
+ private MonitorProvider<?> rootContainerMonitor;
+ private DiskSpaceMonitor diskMonitor;
+
/**
* The controls supported by this backend.
*/
@@ -360,10 +360,18 @@
}
// Register a monitor provider for the environment.
- MonitorProvider<? extends MonitorProviderCfg> monitorProvider =
- rootContainer.getMonitorProvider();
- monitorProviders.add(monitorProvider);
- DirectoryServer.registerMonitorProvider(monitorProvider);
+ rootContainerMonitor = rootContainer.getMonitorProvider();
+ DirectoryServer.registerMonitorProvider(rootContainerMonitor);
+
+ // Register as disk space monitor handler
+ File parentDirectory = getFileForPath(cfg.getDBDirectory());
+ File backendDirectory =
+ new File(parentDirectory, cfg.getBackendId());
+ diskMonitor = new DiskSpaceMonitor(getBackendID() + " backend",
+ backendDirectory, cfg.getDiskLowThreshold(), cfg.getDiskFullThreshold(),
+ 5, TimeUnit.SECONDS, this);
+ diskMonitor.initializeMonitorProvider(null);
+ DirectoryServer.registerMonitorProvider(diskMonitor);
//Register as an AlertGenerator.
DirectoryServer.registerAlertGenerator(this);
@@ -398,13 +406,11 @@
}
}
- // Deregister our monitor providers.
- for (MonitorProvider<?> monitor : monitorProviders)
- {
- DirectoryServer.deregisterMonitorProvider(
- monitor.getMonitorInstanceName().toLowerCase());
- }
- monitorProviders = new ArrayList<MonitorProvider<?>>();
+ DirectoryServer.deregisterMonitorProvider(
+ rootContainerMonitor.getMonitorInstanceName());
+
+ DirectoryServer.deregisterMonitorProvider(
+ diskMonitor.getMonitorInstanceName());
// We presume the server will prevent more operations coming into this
// backend, but there may be existing operations already in the
@@ -755,6 +761,7 @@
public void addEntry(Entry entry, AddOperation addOperation)
throws DirectoryException, CanceledOperationException
{
+ checkDiskSpace(addOperation);
writerBegin();
DN entryDN = entry.getDN();
@@ -799,6 +806,7 @@
public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
throws DirectoryException, CanceledOperationException
{
+ checkDiskSpace(deleteOperation);
writerBegin();
EntryContainer ec;
@@ -843,6 +851,7 @@
ModifyOperation modifyOperation) throws DirectoryException,
CanceledOperationException
{
+ checkDiskSpace(modifyOperation);
writerBegin();
DN entryDN = newEntry.getDN();
@@ -887,7 +896,9 @@
@Override()
public void renameEntry(DN currentDN, Entry entry,
ModifyDNOperation modifyDNOperation)
- throws DirectoryException, CanceledOperationException {
+ throws DirectoryException, CanceledOperationException
+ {
+ checkDiskSpace(modifyDNOperation);
writerBegin();
EntryContainer currentContainer;
@@ -1580,6 +1591,14 @@
baseDNs = newBaseDNs;
}
+
+ if(cfg.getDiskFullThreshold() != newCfg.getDiskFullThreshold() ||
+ cfg.getDiskLowThreshold() != newCfg.getDiskLowThreshold())
+ {
+ diskMonitor.setFullThreshold(newCfg.getDiskFullThreshold());
+ diskMonitor.setLowThreshold(newCfg.getDiskLowThreshold());
+ }
+
// Put the new configuration in place.
this.cfg = newCfg;
}
@@ -1692,6 +1711,10 @@
alerts.put(ALERT_TYPE_BACKEND_ENVIRONMENT_UNUSABLE,
ALERT_DESCRIPTION_BACKEND_ENVIRONMENT_UNUSABLE);
+ alerts.put(ALERT_TYPE_DISK_SPACE_LOW,
+ ALERT_DESCRIPTION_DISK_SPACE_LOW);
+ alerts.put(ALERT_TYPE_DISK_FULL,
+ ALERT_DESCRIPTION_DISK_FULL);
return alerts;
}
@@ -1729,4 +1752,51 @@
new EntryCachePreloader(this);
preloader.preload();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void diskLowThresholdReached(long bytesFree) {
+ Message msg = ERR_JEB_DISK_LOW_THRESHOLD_REACHED.get(
+ getFileForPath(cfg.getDBDirectory()).getPath(), cfg.getBackendId(),
+ bytesFree, Math.max(cfg.getDiskLowThreshold(),
+ cfg.getDiskFullThreshold()));
+ DirectoryServer.sendAlertNotification(this,
+ ALERT_TYPE_DISK_SPACE_LOW, msg);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void diskFullThresholdReached(long bytesFree) {
+ Message msg = ERR_JEB_DISK_FULL_THRESHOLD_REACHED.get(
+ getFileForPath(cfg.getDBDirectory()).getPath(), cfg.getBackendId(),
+ bytesFree, Math.max(cfg.getDiskLowThreshold(),
+ cfg.getDiskFullThreshold()));
+ DirectoryServer.sendAlertNotification(this,
+ ALERT_TYPE_DISK_FULL, msg);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void diskSpaceRestored(long bytesFree) {
+ Message msg = NOTE_JEB_DISK_SPACE_RESTORED.get(bytesFree,
+ getFileForPath(cfg.getDBDirectory()).getPath(), cfg.getBackendId(),
+ Math.max(cfg.getDiskLowThreshold(),
+ cfg.getDiskFullThreshold()));
+ logError(msg);
+ }
+
+ private void checkDiskSpace(Operation operation) throws DirectoryException
+ {
+ if(diskMonitor.isFullThresholdReached() ||
+ (diskMonitor.isLowThresholdReached() && operation != null &&
+ !operation.getClientConnection().hasPrivilege(
+ Privilege.BYPASS_LOCKDOWN, operation)))
+ {
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ WARN_JEB_OUT_OF_DISK_SPACE.get());
+ }
+ }
}
--
Gitblit v1.10.0