mirror of
https://github.com/yacy/yacy_search_server.git
synced 2024-09-19 00:01:41 +02:00
resource observer now uses the Java 6 method to check for free space. thus, disk observing now needs Java 6 installed.
git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@6652 6c8d7289-2bf4-0310-a012-ef5d649a1542
This commit is contained in:
parent
089877f32c
commit
11188cd7eb
|
@ -135,12 +135,12 @@ public class Status {
|
|||
|
||||
// resource observer status
|
||||
if (adminaccess) {
|
||||
if (!sb.observer.getDisksOK()){
|
||||
if (!sb.observer.getDiskAvailable()){
|
||||
final String minFree = Formatter.bytesToString(sb.observer.getMinFreeDiskSpace());
|
||||
prop.put("warningDiskSpaceLow", "1");
|
||||
prop.put("warningDiskSpaceLow_minSpace", minFree);
|
||||
}
|
||||
if (!sb.observer.getMemoryOK()){
|
||||
if (!sb.observer.getMemoryAvailable()){
|
||||
final String minFree = Formatter.bytesToString(sb.observer.getMinFreeMemory() * 1024L);
|
||||
prop.put("warningMemoryLow", "1");
|
||||
prop.put("warningMemoryLow_minSpace", minFree);
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// ResourceObserver.java
|
||||
// -----------------------
|
||||
// part of YaCy
|
||||
// (C) by Detlef Reichl; detlef!reichl()gmx!org
|
||||
// (c) David Wieditz; lotus at mail.berlios.de
|
||||
// first published 6.2.2010
|
||||
//
|
||||
// based on the former code (c) by Detlef Reichl; detlef!reichl()gmx!org
|
||||
// Pforzheim, Germany, 2008
|
||||
//
|
||||
// changes by David Wieditz
|
||||
// part of YaCy
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,84 +24,39 @@
|
|||
|
||||
package de.anomic.crawler;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import net.yacy.kelondro.logging.Log;
|
||||
import net.yacy.kelondro.util.DiskSpace;
|
||||
import net.yacy.kelondro.util.MemoryControl;
|
||||
|
||||
import de.anomic.search.Switchboard;
|
||||
import de.anomic.search.SwitchboardConstants;
|
||||
|
||||
public final class ResourceObserver {
|
||||
// Unknown for now
|
||||
//private static final static long MIN_FREE_MEMORY = 0;
|
||||
// We are called with the cleanup job every five minutes;
|
||||
// the disk usage should be checked with every run
|
||||
private static final int CHECK_DISK_USAGE_FREQ = 1;
|
||||
// The memory usage should be checked on every run
|
||||
private static final int CHECK_MEMORY_USAGE_FREQ = 1;
|
||||
public class ResourceObserver {
|
||||
|
||||
public static final Log log = new Log("RESOURCE OBSERVER");
|
||||
|
||||
// return values for available disk/memory
|
||||
private static final int LOW = 0;
|
||||
private static final int MEDIUM = 1;
|
||||
private static final int HIGH = 2;
|
||||
|
||||
public static final Log log = new Log("RESOURCE OBSERVER");
|
||||
private final Switchboard sb;
|
||||
private final File path; // path to check
|
||||
|
||||
private int checkDiskUsageCount;
|
||||
private int checkMemoryUsageCount;
|
||||
private int disksFree;
|
||||
private int memoryFree;
|
||||
private int normalizedDiskFree = HIGH;
|
||||
private int normalizedMemoryFree = HIGH;
|
||||
private boolean disabledDHT = false;
|
||||
|
||||
/**
|
||||
* The ResourceObserver checks the resources
|
||||
* and pauses crawls if necessary
|
||||
* @param sb the plasmaSwitchboard
|
||||
*/
|
||||
public ResourceObserver(final Switchboard sb) {
|
||||
this.sb = sb;
|
||||
log.logInfo("initializing the resource observer");
|
||||
|
||||
final ArrayList<String> pathsToCheck = new ArrayList<String>();
|
||||
// FIXME whats about the secondary path???
|
||||
// = (getConfig(plasmaSwitchboard.INDEX_SECONDARY_PATH, "");
|
||||
final String[] pathes = {
|
||||
SwitchboardConstants.HTDOCS_PATH,
|
||||
SwitchboardConstants.INDEX_PRIMARY_PATH,
|
||||
SwitchboardConstants.LISTS_PATH,
|
||||
SwitchboardConstants.RANKING_PATH,
|
||||
SwitchboardConstants.WORK_PATH};
|
||||
String path;
|
||||
for (final String element : pathes) {
|
||||
try {
|
||||
path = sb.getConfigPath(element, "").getCanonicalPath();
|
||||
if (path.length() > 0) pathsToCheck.add(path);
|
||||
} catch (final IOException e) {}
|
||||
}
|
||||
|
||||
DiskSpace.init(pathsToCheck);
|
||||
|
||||
if (!DiskSpace.isUsable())
|
||||
log.logWarning("Disk usage returned: " + DiskSpace.getErrorMessage());
|
||||
|
||||
checkDiskUsageCount = 0;
|
||||
checkMemoryUsageCount = 0;
|
||||
disksFree = HIGH;
|
||||
memoryFree = HIGH;
|
||||
this.path = sb.getConfigPath(SwitchboardConstants.INDEX_PRIMARY_PATH, "");
|
||||
}
|
||||
|
||||
public static void initThread() {
|
||||
Switchboard sb = Switchboard.getSwitchboard();
|
||||
// initializing the resourceObserver
|
||||
sb.observer = new ResourceObserver(sb);
|
||||
// run the oberver here a first time
|
||||
final Switchboard sb = Switchboard.getSwitchboard();
|
||||
sb.observer = new ResourceObserver(Switchboard.getSwitchboard());
|
||||
sb.observer.resourceObserverJob();
|
||||
}
|
||||
|
||||
|
@ -109,77 +66,94 @@ public final class ResourceObserver {
|
|||
public void resourceObserverJob() {
|
||||
MemoryControl.setDHTkbytes(getMinFreeMemory());
|
||||
|
||||
checkDiskUsageCount++;
|
||||
checkMemoryUsageCount++;
|
||||
int tmpDisksFree = HIGH;
|
||||
int tmpMemoryFree = HIGH;
|
||||
if (checkDiskUsageCount >= CHECK_DISK_USAGE_FREQ) {
|
||||
checkDiskUsageCount = 0;
|
||||
tmpDisksFree = checkDisks();
|
||||
disksFree = tmpDisksFree;
|
||||
}
|
||||
if (checkMemoryUsageCount >= CHECK_MEMORY_USAGE_FREQ) {
|
||||
checkMemoryUsageCount = 0;
|
||||
tmpMemoryFree = checkMemory();
|
||||
memoryFree = tmpMemoryFree;
|
||||
}
|
||||
normalizedDiskFree = getNormalizedDiskFree();
|
||||
normalizedMemoryFree = getNormalizedMemoryFree();
|
||||
|
||||
if (tmpDisksFree < HIGH || tmpMemoryFree < HIGH) {
|
||||
if (tmpDisksFree < HIGH && !sb.crawlJobIsPaused(SwitchboardConstants.CRAWLJOB_LOCAL_CRAWL)) {
|
||||
log.logInfo("pausing local crawls");
|
||||
sb.pauseCrawlJob(SwitchboardConstants.CRAWLJOB_LOCAL_CRAWL);
|
||||
}
|
||||
if (tmpDisksFree < HIGH && !sb.crawlJobIsPaused(SwitchboardConstants.CRAWLJOB_REMOTE_TRIGGERED_CRAWL)) {
|
||||
log.logInfo("pausing remote triggered crawls");
|
||||
sb.pauseCrawlJob(SwitchboardConstants.CRAWLJOB_REMOTE_TRIGGERED_CRAWL);
|
||||
}
|
||||
if ((tmpDisksFree == LOW || tmpMemoryFree < HIGH) && sb.getConfigBool(SwitchboardConstants.INDEX_RECEIVE_ALLOW, false)) {
|
||||
log.logInfo("disabling index receive");
|
||||
sb.setConfig(SwitchboardConstants.INDEX_RECEIVE_ALLOW, false);
|
||||
sb.peers.mySeed().setFlagAcceptRemoteIndex(false);
|
||||
disabledDHT = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (DiskSpace.isUsable()) {
|
||||
if(disabledDHT) { // we were wrong!
|
||||
log.logInfo("enabling index receive");
|
||||
sb.setConfig(SwitchboardConstants.INDEX_RECEIVE_ALLOW, true);
|
||||
sb.peers.mySeed().setFlagAcceptRemoteIndex(true);
|
||||
disabledDHT = false;
|
||||
}
|
||||
log.logInfo("run completed; everything in order");
|
||||
}
|
||||
else
|
||||
log.logInfo("The observer is out of order: " + DiskSpace.getErrorMessage());
|
||||
}
|
||||
if (normalizedDiskFree < HIGH || normalizedMemoryFree < HIGH) {
|
||||
|
||||
if (normalizedDiskFree < HIGH) { // pause crawls
|
||||
if (!sb.crawlJobIsPaused(SwitchboardConstants.CRAWLJOB_LOCAL_CRAWL)) {
|
||||
log.logInfo("pausing local crawls");
|
||||
sb.pauseCrawlJob(SwitchboardConstants.CRAWLJOB_LOCAL_CRAWL);
|
||||
}
|
||||
if (!sb.crawlJobIsPaused(SwitchboardConstants.CRAWLJOB_REMOTE_TRIGGERED_CRAWL)) {
|
||||
log.logInfo("pausing remote triggered crawls");
|
||||
sb.pauseCrawlJob(SwitchboardConstants.CRAWLJOB_REMOTE_TRIGGERED_CRAWL);
|
||||
}
|
||||
}
|
||||
|
||||
if ((normalizedDiskFree == LOW || normalizedMemoryFree < HIGH) && sb.getConfigBool(SwitchboardConstants.INDEX_RECEIVE_ALLOW, false)) {
|
||||
log.logInfo("disabling index receive");
|
||||
sb.setConfig(SwitchboardConstants.INDEX_RECEIVE_ALLOW, false);
|
||||
sb.peers.mySeed().setFlagAcceptRemoteIndex(false);
|
||||
disabledDHT = true;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if(disabledDHT) { // we were wrong!
|
||||
log.logInfo("enabling index receive");
|
||||
sb.setConfig(SwitchboardConstants.INDEX_RECEIVE_ALLOW, true);
|
||||
sb.peers.mySeed().setFlagAcceptRemoteIndex(true);
|
||||
disabledDHT = false;
|
||||
}
|
||||
log.logInfo("resources ok");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the amount of disk space available
|
||||
* @return <ul>
|
||||
* <li><code>HIGH</code> if disk space is available</li>
|
||||
* <li><code>MEDIUM</code> if low disk space is available</li>
|
||||
* <li><code>LOW</code> if lower than hardlimit disk space is available</li>
|
||||
* </ul>
|
||||
*/
|
||||
private int getNormalizedDiskFree() {
|
||||
final long currentSpace = getUsableSpace(this.path);
|
||||
if(currentSpace < 1L) return HIGH;
|
||||
int ret = HIGH;
|
||||
|
||||
if (currentSpace < getMinFreeDiskSpace()) {
|
||||
log.logWarning("Volume " + this.path.toString() + ": free space (" + (currentSpace / 1024 / 1024) + " MB) is too low (< " + (getMinFreeDiskSpace() / 1024 / 1024) + " MB)");
|
||||
ret = MEDIUM;
|
||||
}
|
||||
if (currentSpace < getMinFreeDiskSpace_hardlimit()) {
|
||||
ret = LOW;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int getNormalizedMemoryFree() {
|
||||
if(!MemoryControl.getDHTallowed()) return LOW;
|
||||
return HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if disk space is available
|
||||
*/
|
||||
public boolean getDisksOK () {
|
||||
return disksFree == HIGH;
|
||||
public boolean getDiskAvailable() {
|
||||
return normalizedDiskFree == HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if memory is available
|
||||
*/
|
||||
public boolean getMemoryOK () {
|
||||
return memoryFree == HIGH;
|
||||
public boolean getMemoryAvailable() {
|
||||
return normalizedMemoryFree == HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return amount of space (bytes) that should be kept free
|
||||
*/
|
||||
public long getMinFreeDiskSpace () {
|
||||
public long getMinFreeDiskSpace() {
|
||||
return sb.getConfigLong(SwitchboardConstants.DISK_FREE, 3000) /* MiB */ * 1024L * 1024L;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return amount of space (bytes) that should at least be kept free
|
||||
*/
|
||||
public long getMinFreeDiskSpace_hardlimit () {
|
||||
public long getMinFreeDiskSpace_hardlimit() {
|
||||
return sb.getConfigLong(SwitchboardConstants.DISK_FREE_HARDLIMIT, 100) /* MiB */ * 1024L * 1024L;
|
||||
}
|
||||
|
||||
|
@ -190,39 +164,25 @@ public final class ResourceObserver {
|
|||
return sb.getConfigLong(SwitchboardConstants.MEMORY_ACCEPTDHT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the amount of disk space available
|
||||
* @return <ul>
|
||||
* <li><code>HIGH</code> if disk space is available</li>
|
||||
* <li><code>MEDIUM</code> if low disk space is available</li>
|
||||
* <li><code>LOW</code> if lower than hardlimit or 1/5 disk space is available (the max)</li>
|
||||
* </ul>
|
||||
*/
|
||||
private int checkDisks() {
|
||||
int ret = HIGH;
|
||||
|
||||
if (!DiskSpace.isUsable ())
|
||||
return HIGH;
|
||||
/**
|
||||
* This method calls File.getUsableSpace() from Java 6.
|
||||
* @param file the path to be checked
|
||||
* @return "The number of available bytes on the partition or 0L if the abstract pathname does not name a partition." -1L on error.
|
||||
* @author lotus at mail.berlios.de
|
||||
*/
|
||||
public static long getUsableSpace(final File file) {
|
||||
try {
|
||||
final Class<?> File6 = Class.forName("java.io.File");
|
||||
final Class<?>[] param = {File.class, String.class };
|
||||
final Constructor<?> File6Constructor = File6.getConstructor(param);
|
||||
final Object file6 = File6Constructor.newInstance(file, "");
|
||||
final Method getFreeSpace = file6.getClass().getMethod("getUsableSpace", (Class[])null);
|
||||
final Object space = getFreeSpace.invoke(file6, (Object[])null);
|
||||
return Long.parseLong(space.toString());
|
||||
} catch (Throwable e) {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
final HashMap<String, long[]> usage = DiskSpace.getDiskUsage();
|
||||
long[] val;
|
||||
for (final Map.Entry<String, long[]> entry: usage.entrySet()) {
|
||||
val = entry.getValue();
|
||||
log.logInfo("df of Volume " + entry.getKey() + ": " + (val[1] / 1024 / 1024) + " MB");
|
||||
if (val[1] < getMinFreeDiskSpace()) {
|
||||
log.logWarning("Volume " + entry.getKey() + ": free space (" + (val[1] / 1024 / 1024) + " MB) is too low (< " + (getMinFreeDiskSpace() / 1024 / 1024) + " MB)");
|
||||
ret = MEDIUM;
|
||||
}
|
||||
if (val[1] < Math.max(getMinFreeDiskSpace() / 5L, getMinFreeDiskSpace_hardlimit())) {
|
||||
ret = LOW;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int checkMemory() {
|
||||
if(!MemoryControl.getDHTallowed()) return LOW;
|
||||
return HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,402 +0,0 @@
|
|||
// diskUsage.java
|
||||
// -----------------------
|
||||
// part of YaCy
|
||||
// (C) by Detlef Reichl; detlef!reichl()gmx!org
|
||||
// Pforzheim, Germany, 2008
|
||||
//
|
||||
// [MC] made many changes to remove side-effect-based routines towards a more functional programming style
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
// The HashMap contains the following values:
|
||||
//
|
||||
// key = the device name e.g. /dev/hda1, on windows the drive e.g. c:
|
||||
// value[0] = the total space of the volume, on windows not used
|
||||
// value[1] = the free space of the volume
|
||||
|
||||
package net.yacy.kelondro.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import net.yacy.kelondro.logging.Log;
|
||||
|
||||
|
||||
public class DiskSpace {
|
||||
|
||||
private static Log log = new Log("DISK USAGE");
|
||||
|
||||
private static final List<String> allVolumes = new ArrayList<String>();
|
||||
private static final List<String> allMountPoints = new ArrayList<String>();
|
||||
private static final List<Boolean> usedVolumes = new ArrayList<Boolean>();
|
||||
|
||||
private static final List<String> yacyUsedVolumes = new ArrayList<String>();
|
||||
private static final List<String> yacyUsedMountPoints = new ArrayList<String>();
|
||||
|
||||
private static int usedOS = -1;
|
||||
private static String usageError = null;
|
||||
private static String windowsCommand = null;
|
||||
|
||||
|
||||
// Unix-like
|
||||
private static final int AIX = 0; // IBM
|
||||
private static final int BS2000 = 1; // Fujitsu Siemens (oficial BS2000/OSD)
|
||||
//private static final int BSD = 2; // all kind of BSD
|
||||
private static final int HAIKU = 3; // like BeOS; does not have a JRE til now, but they are working on it
|
||||
//private static final int HP_UX = 4; // Hewlett-Packard
|
||||
private static final int TRU64 = 5; // Hewlett-Packard
|
||||
//private static final int IRIX = 6; // sgi
|
||||
private static final int LINUX = 7; // all kind of linux
|
||||
//private static final int MAC_OS_X = 8; // Apple
|
||||
private static final int MINIX = 9; // don't know if there even is a JRE for minix...
|
||||
//private static final int SOLARIS = 10; // SUN
|
||||
//private static final int SUNOS = 11; // The latest SunOS version is from 1990 but the Solaris java refferer remains SunOS
|
||||
private static final int UNICOS = 12; // cray
|
||||
|
||||
private static final int UNIX_END = UNICOS;
|
||||
|
||||
// Windows dos based
|
||||
//private static final int WINDOWS_95 = 13;
|
||||
//private static final int WINDOWS_98 = 14;
|
||||
//private static final int WINDOWS_ME = 15;
|
||||
|
||||
// Windows WinNT based
|
||||
//private static final int WINDOWS_NT = 16;
|
||||
//private static final int WINDOWS_2000 = 17;
|
||||
//private static final int WINDOWS_XP = 18;
|
||||
//private static final int WINDOWS_SERVER = 19;
|
||||
//private static final int WINDOWS_VISTA = 20;
|
||||
//private static final int WINDOWS_7 = 21;
|
||||
|
||||
// don't change order of names!
|
||||
// (look above)
|
||||
private static final String[] OSname = {
|
||||
"aix", "bs2000", "bsd", "haiku", "hp-ux", "tru64", "irix", "linux", "mac os x", "minix",
|
||||
"solaris", "sunos", "unicos",
|
||||
"windows 95", "windows 98", "windows me",
|
||||
"windows nt", "windows 2000", "windows xp", "windows server", "windows vista", "windows 7"};
|
||||
|
||||
//////////////////
|
||||
// public API //
|
||||
//////////////////
|
||||
|
||||
public static void init(final ArrayList<String> pathsToCheck) {
|
||||
if (usedOS >= 0) return; // prevent double initialization
|
||||
usedOS = getOS();
|
||||
if (usedOS == -1) {
|
||||
return;
|
||||
}
|
||||
usageError = null;
|
||||
|
||||
if (usedOS <= UNIX_END) {
|
||||
// some kind of *nix
|
||||
dfUnixGetVolumes();
|
||||
for (int i = 0; i < allMountPoints.size(); i++)
|
||||
usedVolumes.add(false);
|
||||
checkVolumesInUseUnix ("DATA");
|
||||
checkMappedSubDirs(pathsToCheck);
|
||||
|
||||
for (int i = 0; i < allVolumes.size(); i++){
|
||||
if (usedVolumes.get(i)) {
|
||||
yacyUsedVolumes.add(allVolumes.get (i));
|
||||
yacyUsedMountPoints.add(allMountPoints.get (i));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// all Windows versions
|
||||
initWindowsCommandVersion();
|
||||
checkStartVolume();
|
||||
checkMappedSubDirs(pathsToCheck);
|
||||
}
|
||||
if (yacyUsedVolumes.size() < 1)
|
||||
usageError = "found no volumes";
|
||||
}
|
||||
|
||||
public static HashMap<String, long[]> getDiskUsage () {
|
||||
if (usageError != null) return null;
|
||||
|
||||
if (usedOS <= UNIX_END)
|
||||
return dfUnix();
|
||||
else
|
||||
return dfWindows();
|
||||
}
|
||||
|
||||
public static boolean isUsable() {
|
||||
return usageError == null;
|
||||
}
|
||||
|
||||
public static int getNumUsedVolumes () {
|
||||
return yacyUsedVolumes.size();
|
||||
}
|
||||
|
||||
public static String getErrorMessage() {
|
||||
return usageError;
|
||||
}
|
||||
|
||||
////////////
|
||||
// Unix //
|
||||
////////////
|
||||
|
||||
private static HashMap<String, long[]> dfUnix() {
|
||||
final HashMap<String, long[]> diskUsages = new HashMap<String, long[]>();
|
||||
try {
|
||||
final List<String> lines = dfUnixExec();
|
||||
nextLine: for (final String line: lines){
|
||||
if (line.length() > 0 && line.charAt(0) != '/') continue;
|
||||
final String[] tokens = line.split(" +", 6);
|
||||
if (tokens.length < 6) continue;
|
||||
for (int i = 0; i < yacyUsedVolumes.size(); i++){
|
||||
if (yacyUsedVolumes.get(i).equals(tokens[0])) {
|
||||
final long[] vals = new long[2];
|
||||
try { vals[0] = Long.valueOf(tokens[1]); } catch (final NumberFormatException e) { continue nextLine; }
|
||||
try { vals[1] = Long.valueOf(tokens[3]); } catch (final NumberFormatException e) { continue nextLine; }
|
||||
vals[0] *= 1024;
|
||||
vals[1] *= 1024;
|
||||
diskUsages.put(yacyUsedMountPoints.get(i), vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
return diskUsages;
|
||||
} catch (final IOException e) {
|
||||
usageError = "dfUnix: " + e.getMessage();
|
||||
return diskUsages;
|
||||
}
|
||||
}
|
||||
|
||||
private static void dfUnixGetVolumes() {
|
||||
try {
|
||||
final List<String> lines = dfUnixExec();
|
||||
|
||||
nextLine: for (final String line: lines){
|
||||
if (line.length() > 0 && line.charAt(0) != '/') continue;
|
||||
final String[] tokens = line.split(" +", 6);
|
||||
if (tokens.length < 6) continue;
|
||||
for (int i = 0; i < allMountPoints.size(); i++) {
|
||||
if (tokens[5].trim().compareTo(allMountPoints.get(i)) > 0) {
|
||||
allMountPoints.add(i, tokens[5].trim());
|
||||
allVolumes.add(i, tokens[0]);
|
||||
continue nextLine;
|
||||
}
|
||||
}
|
||||
allMountPoints.add(allMountPoints.size(), tokens[5]);
|
||||
allVolumes.add(allVolumes.size(), tokens[0]);
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
usageError = "error during dfUnixGetVolumes: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> dfUnixExec() throws IOException {
|
||||
|
||||
// -k set blocksize to 1024
|
||||
// confirmed with tests:
|
||||
// Linux
|
||||
// verified with man pages or other docs:
|
||||
// AIX, BS2000, *BSD, HP-UX, IRIX, minix, Mac OS X, Solaris, Tru64, UNICOS
|
||||
|
||||
// -l list local filesystems only
|
||||
// confirmed with tests:
|
||||
// Linux
|
||||
// verified with man pages or other docs:
|
||||
// AIX, BS2000, *BSD, HP-UX, IRIX, minix, Mac OS X, Solaris, UNICOS
|
||||
|
||||
// please report all successes or fails for non-confirmed systems to
|
||||
// detlef!reichl()gmx!org. Thanks!
|
||||
|
||||
final List<String> processArgs = new ArrayList<String>();
|
||||
processArgs.add("df");
|
||||
processArgs.add("-k");
|
||||
// Some systems need the additional -P parameter to return the data in Posix format.
|
||||
// Without it the mount point will be in the 7th and not in the 6th column
|
||||
// On Linux, -P is used to have everything on one line, for lvm or based setup
|
||||
if (usedOS == AIX || usedOS == BS2000 || usedOS == MINIX || usedOS == UNICOS || usedOS == LINUX)
|
||||
processArgs.add("-P");
|
||||
// Tru64 does not know the -l parameter
|
||||
// For haiku i didn't found online docs at all; so better exclude it
|
||||
if (usedOS != TRU64 && usedOS != HAIKU)
|
||||
processArgs.add("-l");
|
||||
|
||||
final List<String> lines = ConsoleInterface.getConsoleOutput(processArgs, log);
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static void checkVolumesInUseUnix (final String path) {
|
||||
final File file = new File(path);
|
||||
final File[] fileList = file.listFiles();
|
||||
if (fileList == null) {
|
||||
// the file is not a directory
|
||||
return;
|
||||
}
|
||||
String base;
|
||||
String dir;
|
||||
|
||||
for (final File element : fileList) {
|
||||
if (element.isDirectory()) {
|
||||
try {
|
||||
dir = element.getCanonicalPath();
|
||||
} catch (final IOException e) {
|
||||
usageError = "checkVolumesInUseUnix(1): " + e.getMessage();
|
||||
break;
|
||||
}
|
||||
if (dir.endsWith ("HTCACHE")
|
||||
|| dir.endsWith ("HTDOCS")
|
||||
|| dir.endsWith ("LOCALE")
|
||||
|| dir.endsWith ("RANKING")
|
||||
|| dir.endsWith ("RELEASE")
|
||||
|| dir.endsWith ("collection.0028.commons")) {
|
||||
checkPathUsageUnix (dir);
|
||||
} else if (dir != null) {
|
||||
checkVolumesInUseUnix (dir);
|
||||
} else {
|
||||
log.logSevere("directory is null: " + element);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
base = element.getCanonicalPath();
|
||||
} catch (final IOException e) {
|
||||
usageError = "checkVolumesInUseUnix(2): " + e.getMessage();
|
||||
break;
|
||||
}
|
||||
checkPathUsageUnix (base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////
|
||||
// Windows //
|
||||
///////////////
|
||||
|
||||
private static void initWindowsCommandVersion () {
|
||||
windowsCommand = null;
|
||||
final String os = System.getProperty("os.name").toLowerCase();
|
||||
final String[] oses = {"windows 95", "windows 98", "windows me"};
|
||||
|
||||
for (final String element : oses) {
|
||||
if (os.indexOf(element) >= 0){
|
||||
windowsCommand = "command.com";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (windowsCommand == null)
|
||||
windowsCommand = "cmd.exe";
|
||||
}
|
||||
|
||||
private static void checkStartVolume() {
|
||||
final File file = new File("DATA");
|
||||
|
||||
String path = null;
|
||||
try { path = file.getCanonicalPath(); } catch (final IOException e) {
|
||||
usageError = "Cant get DATA directory";
|
||||
return;
|
||||
}
|
||||
if (path.length() < 6)
|
||||
return;
|
||||
yacyUsedVolumes.add(path);
|
||||
}
|
||||
|
||||
private static HashMap<String, long[]> dfWindows() {
|
||||
final HashMap<String, long[]> diskUsages = new HashMap<String, long[]>();
|
||||
for (int i = 0; i < yacyUsedVolumes.size(); i++){
|
||||
final List<String> processArgs = new ArrayList<String>();
|
||||
processArgs.add(windowsCommand);
|
||||
processArgs.add("/c");
|
||||
processArgs.add("dir");
|
||||
processArgs.add("\"" + yacyUsedVolumes.get(i) + "\"");
|
||||
|
||||
try {
|
||||
final List<String> lines = ConsoleInterface.getConsoleOutput(processArgs, log);
|
||||
|
||||
String line = "";
|
||||
for (int l = lines.size() - 1; l >= 0; l--) {
|
||||
line = lines.get(l).trim();
|
||||
if (line.length() > 0) break;
|
||||
}
|
||||
if (line.length() == 0) {
|
||||
usageError = "unable to get free size of volume " + yacyUsedVolumes.get(i);
|
||||
return diskUsages;
|
||||
}
|
||||
|
||||
final String[] tokens = line.trim().split(" ++");
|
||||
final long[] vals = new long[2];
|
||||
vals[0] = -1;
|
||||
try { vals[1] = Long.valueOf(tokens[2].replaceAll("[.,]", "")); } catch (final NumberFormatException e) {continue;}
|
||||
diskUsages.put (yacyUsedVolumes.get(i), vals);
|
||||
} catch (final IOException e) {
|
||||
usageError = "dfWindows: " + e.getMessage();
|
||||
return diskUsages;
|
||||
}
|
||||
|
||||
}
|
||||
return diskUsages;
|
||||
}
|
||||
|
||||
/////////////
|
||||
// common //
|
||||
/////////////
|
||||
|
||||
private static int getOS() {
|
||||
final String os = System.getProperty("os.name").toLowerCase();
|
||||
for (int i = 0; i < OSname.length; i++)
|
||||
{
|
||||
if (os.indexOf(OSname[i]) >= 0)
|
||||
return i;
|
||||
}
|
||||
usageError = "unknown operating system (" + System.getProperty("os.name") + ")";
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static void checkMappedSubDirs (final ArrayList<String> pathsToCheck) {
|
||||
for (final String path : pathsToCheck) {
|
||||
if (usedOS <= UNIX_END)
|
||||
checkPathUsageUnix (path);
|
||||
else
|
||||
checkPathUsageWindows (path);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPathUsageUnix (final String path) {
|
||||
for (int i = 0; i < allMountPoints.size(); i++){
|
||||
if (path.startsWith (allMountPoints.get(i))) {
|
||||
usedVolumes.set(i, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPathUsageWindows(final String path) {
|
||||
// we would need to ask every path by "dir" as asking the root is not hardlink-proof:
|
||||
// yacyUsedVolumes.add(path);
|
||||
return;
|
||||
/*
|
||||
int index = -1;
|
||||
final String sub = path.substring(0, 1); // ?? nur ein character?
|
||||
try {
|
||||
index = yacyUsedVolumes.indexOf(sub);
|
||||
} catch (final IndexOutOfBoundsException e) {
|
||||
usageError = "internal error while checking used windows volumes";
|
||||
return;
|
||||
}
|
||||
if (index < 0)
|
||||
yacyUsedVolumes.add(sub);
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user