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); } 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))) 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. } 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(); } } 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. } } 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. 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(); } 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); } } 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); } } 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 '%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 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 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 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 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 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 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();