b8cfaec
diff -urNp inn-2.5.0-orig/doc/pod/makehistory.pod inn-2.5.0/doc/pod/makehistory.pod
b8cfaec
--- inn-2.5.0-orig/doc/pod/makehistory.pod	2009-06-24 09:54:24.000000000 +0200
b8cfaec
+++ inn-2.5.0/doc/pod/makehistory.pod	2009-06-24 09:56:58.000000000 +0200
b8cfaec
@@ -5,7 +5,7 @@ makehistory - Initialize or rebuild INN 
b8cfaec
 =head1 SYNOPSIS
b8cfaec
 
b8cfaec
 B<makehistory> [B<-abFIOSx>] [B<-f> I<filename>] [B<-l> I<count>]
b8cfaec
-[B<-s> I<size>] [B<-T> I<tmpdir>]
b8cfaec
+[B<-L> I<load-average>] [B<-s> I<size>] [B<-T> I<tmpdir>]
b8cfaec
 
b8cfaec
 =head1 DESCRIPTION
b8cfaec
 
b8cfaec
@@ -89,6 +89,16 @@ specify the temporary storage location. 
b8cfaec
 with buffindexed, because buffindexed does not need sorted
b8cfaec
 overview and no batching is done.
b8cfaec
 
b8cfaec
+=item B<-L> I<load-average>
b8cfaec
+
b8cfaec
+Temporarily pause activities if the system load average exceeds the
b8cfaec
+specified level I<load-average>.  This allows B<makehistory> to run
b8cfaec
+on a system being used for other purposes without monopolizing system
b8cfaec
+resources and thus making the response time for other applications
b8cfaec
+unacceptably slow.  Using nice(1) does not help much for that because
b8cfaec
+the problem comes from disk I/O usage, and ionice(1) is not always
b8cfaec
+available or efficient.
b8cfaec
+
b8cfaec
 =item B<-O>
b8cfaec
 
b8cfaec
 Create the overview database as well as the F<history> file.  Overview
b8cfaec
diff -urNp inn-2.5.0-orig/expire/makehistory.c inn-2.5.0/expire/makehistory.c
b8cfaec
--- inn-2.5.0-orig/expire/makehistory.c	2009-06-24 09:54:24.000000000 +0200
b8cfaec
+++ inn-2.5.0/expire/makehistory.c	2009-06-24 10:05:02.000000000 +0200
b8cfaec
@@ -24,8 +24,28 @@
b8cfaec
 #include "inn/vector.h"
b8cfaec
 #include "inn/wire.h"
b8cfaec
 
b8cfaec
+/*
b8cfaec
+**  If we have getloadavg, include the appropriate header file.  Otherwise,
b8cfaec
+**  just assume that we always have a load of 0.
b8cfaec
+*/
b8cfaec
+#if HAVE_GETLOADAVG
b8cfaec
+# if HAVE_SYS_LOADAVG_H
b8cfaec
+#  include <sys/loadavg.h>
b8cfaec
+# endif
b8cfaec
+#else
b8cfaec
+static int
b8cfaec
+getloadavg(double loadavg[], int nelem)
b8cfaec
+{
b8cfaec
+   int i;
b8cfaec
+
b8cfaec
+   for (i = 0; i < nelem && i < 3; i++)
b8cfaec
+        loadavg[i] = 0;
b8cfaec
+   return i;
b8cfaec
+}
b8cfaec
+#endif
b8cfaec
+
b8cfaec
 static const char usage[] = "\
b8cfaec
-Usage: makehistory [-abFIOSx] [-f file] [-l count] [-s size] [-T tmpdir]\n\
b8cfaec
+Usage: makehistory [-abFIOSx] [-f file] [-l count] [-L load] [-s size] [-T tmpdir]\n\
b8cfaec
 \n\
b8cfaec
     -a          open output history file in append mode\n\
b8cfaec
     -b          delete bad articles from spool\n\
b8cfaec
@@ -33,6 +53,7 @@ Usage: makehistory [-abFIOSx] [-f file] 
b8cfaec
     -f file     write history entries to file (default $pathdb/history)\n\
b8cfaec
     -I          do not create overview for articles numbered below lowmark\n\
b8cfaec
     -l count    size of overview updates (default 10000)\n\
b8cfaec
+    -L load     pause when load average exceeds threshold\n\
b8cfaec
     -O          create overview entries for articles\n\
b8cfaec
     -S          write overview data to standard output\n\
b8cfaec
     -s size     size new history database for approximately size entries\n\
b8cfaec
@@ -810,6 +831,8 @@ main(int argc, char **argv)
b8cfaec
 {
b8cfaec
     ARTHANDLE *art = NULL;
b8cfaec
     bool AppendMode;
b8cfaec
+    int LoadAverage;
b8cfaec
+    double load[1];
b8cfaec
     int i;
b8cfaec
     bool val;
b8cfaec
     char *HistoryDir;
b8cfaec
@@ -837,9 +860,10 @@ main(int argc, char **argv)
b8cfaec
     DoOverview = false;
b8cfaec
     Fork = false;
b8cfaec
     AppendMode = false;
b8cfaec
+    LoadAverage = 0;
b8cfaec
     NoHistory = false;
b8cfaec
 
b8cfaec
-    while ((i = getopt(argc, argv, "abFf:Il:OSs:T:x")) != EOF) {
b8cfaec
+    while ((i = getopt(argc, argv, "abFf:Il:L:OSs:T:x")) != EOF) {
b8cfaec
 	switch(i) {
b8cfaec
 	case 'a':
b8cfaec
 	    AppendMode = true;
b8cfaec
@@ -859,6 +883,9 @@ main(int argc, char **argv)
b8cfaec
 	case 'l':
b8cfaec
 	    OverTmpSegSize = atoi(optarg);
b8cfaec
 	    break;
b8cfaec
+	case 'L':
b8cfaec
+	    LoadAverage = atoi(optarg);
b8cfaec
+	    break;
b8cfaec
 	case 'O':
b8cfaec
 	    DoOverview = true;
b8cfaec
 	    break;
b8cfaec
@@ -956,7 +983,7 @@ main(int argc, char **argv)
b8cfaec
 
b8cfaec
     /*
b8cfaec
      * Scan the entire spool, nuke any bad arts if needed, and process each
b8cfaec
-     * article.
b8cfaec
+     * article. We take a break when the load is too high.
b8cfaec
      */
b8cfaec
 	
b8cfaec
     while ((art = SMnext(art, RETR_ALL)) != NULL) {
b8cfaec
@@ -965,7 +992,15 @@ main(int argc, char **argv)
b8cfaec
 		SMcancel(*art->token);
b8cfaec
 	    continue;
b8cfaec
 	}
b8cfaec
+
b8cfaec
 	DoArt(art);
b8cfaec
+
b8cfaec
+        if (LoadAverage > 0) {
b8cfaec
+            while (getloadavg(load, 1) > 0 &&
b8cfaec
+                   (int) (load[0]) >= LoadAverage) {
b8cfaec
+                 sleep(1);
b8cfaec
+            }
b8cfaec
+        }
b8cfaec
     }
b8cfaec
 
b8cfaec
     if (!NoHistory) {