---------------------
PatchSet 867 
Date: 2000/11/25 22:34:43
Author: rbcollins
Branch: store_check
Tag: (none) 
Log:
initial checking routeinf for ufs in place along with basic event loop. now onto scheduling and some nicer debug info.

Members: 
	src/cf.data.pre:1.4->1.4.8.1 
	src/main.c:1.5->1.5.6.1 
	src/protos.h:1.5->1.5.4.1 
	src/store.c:1.5->1.5.4.1 
	src/store_rebuild.c:1.5->1.5.6.1 
	src/structs.h:1.7->1.7.4.1 
	src/fs/aufs/store_dir_aufs.c:1.5->1.5.6.1 
	src/fs/coss/store_dir_coss.c:1.3->1.3.8.1 
	src/fs/diskd/store_dir_diskd.c:1.4->1.4.6.1 
	src/fs/ufs/store_dir_ufs.c:1.4->1.4.6.1 

Index: squid/src/cf.data.pre
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v
retrieving revision 1.4
retrieving revision 1.4.8.1
diff -u -r1.4 -r1.4.8.1
--- squid/src/cf.data.pre	3 Nov 2000 08:39:20 -0000	1.4
+++ squid/src/cf.data.pre	25 Nov 2000 22:34:43 -0000	1.4.8.1
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.4 2000/11/03 08:39:20 hno Exp $
+# $Id: cf.data.pre,v 1.4.8.1 2000/11/25 22:34:43 rbcollins Exp $
 #
 #
 # SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -3271,6 +3271,15 @@
 	Set this to 'round-robin' as an alternative.
 DOC_END
 
+NAME: store_background_check_rate
+TYPE: int
+LOC: Config.store_background_check_rate
+DEFAULT: 50
+DOC_START
+	The number of entries to check on each store background check. Low 
+	numbers (<100) are good.
+DOC_END
+
 NAME: forward_log
 IFDEF: WIP_FWD_LOG
 TYPE: string
Index: squid/src/main.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/main.c,v
retrieving revision 1.5
retrieving revision 1.5.6.1
diff -u -r1.5 -r1.5.6.1
--- squid/src/main.c	10 Nov 2000 16:36:45 -0000	1.5
+++ squid/src/main.c	25 Nov 2000 22:34:43 -0000	1.5.6.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.c,v 1.5 2000/11/10 16:36:45 hno Exp $
+ * $Id: main.c,v 1.5.6.1 2000/11/25 22:34:43 rbcollins Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -101,8 +101,7 @@
 	"       -F        Don't serve any requests until store is rebuilt.\n"
 	"       -N        No daemon mode.\n"
 	"       -R        Do not set REUSEADDR on port.\n"
-	"       -S force  Force double-check swap during rebuild.\n"
-        "       -S reportonly Force double-check but do not attempt repair.\n"
+	"       -S        Force debug double-check swap during rebuild. [stops on errors]\n"
 	"       -V        Virtual host httpd-accelerator.\n"
 	"       -X        Force full debugging.\n"
 	"       -Y        Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.\n",
@@ -116,7 +115,7 @@
     extern char *optarg;
     int c;
 
-    while ((c = getopt(argc, argv, "CDFNRS:VYXa:d:f:hk:m::su:vz?")) != -1) {
+    while ((c = getopt(argc, argv, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) {
 	switch (c) {
 	case 'C':
 	    opt_catch_signals = 0;
@@ -134,14 +133,8 @@
 	    opt_reuseaddr = 0;
 	    break;
 	case 'S':
-            if ((int) strlen(optarg) < 1) 
-                usage();
-            else if (!strncmp(optarg, "force", strlen(optarg)))
-                opt_store_doublecheck = DBLCHECK_FORCE; /* trigger a doublecheck on startup */
-            else if (!strncmp(optarg, "reportonly", strlen(optarg)))
-                opt_store_doublecheck = DBLCHECK_REPORTONLY; /* trigger a doublecheck that doesn't repair */ 
-            else
-                usage();
+            /* trigger a doublecheck that doesn't repair */
+            opt_store_doublecheck = DBLCHECK_REPORTONLY; 
 	    break;
 	case 'V':
 	    vhost_mode = 1;
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.5
retrieving revision 1.5.4.1
diff -u -r1.5 -r1.5.4.1
--- squid/src/protos.h	14 Nov 2000 13:03:47 -0000	1.5
+++ squid/src/protos.h	25 Nov 2000 22:34:43 -0000	1.5.4.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.5 2000/11/14 13:03:47 adri Exp $
+ * $Id: protos.h,v 1.5.4.1 2000/11/25 22:34:43 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -822,6 +822,7 @@
 extern int storeUnlockObject(StoreEntry *);
 extern int storePendingNClients(const StoreEntry *);
 extern EVH storeMaintainSwapSpace;
+extern EVH storeBackgroundCheck;
 extern void storeExpireNow(StoreEntry *);
 extern void storeReleaseRequest(StoreEntry *);
 extern off_t storeLowestMemReaderOffset(const StoreEntry *);
Index: squid/src/store.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store.c,v
retrieving revision 1.5
retrieving revision 1.5.4.1
diff -u -r1.5 -r1.5.4.1
--- squid/src/store.c	18 Nov 2000 11:01:27 -0000	1.5
+++ squid/src/store.c	25 Nov 2000 22:34:43 -0000	1.5.4.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store.c,v 1.5 2000/11/18 11:01:27 adri Exp $
+ * $Id: store.c,v 1.5.4.1 2000/11/25 22:34:43 rbcollins Exp $
  *
  * DEBUG: section 20    Storage Manager
  * AUTHOR: Harvest Derived
@@ -770,6 +770,68 @@
 }
 
 
+/*
+ * This routine is kicked off from main.c. It routinely checks the files by 
+ * swap entry to ensure they are still valid. This will catch failing disks, 
+ * half written entries and the like.
+ *
+ * This version works from store entry down to the files. An alternative would
+ * be to work from files up to the matching storeentry.
+ */
+
+static int
+storeBackgroundCheckEntry(StoreEntry * e)
+{
+    SwapDir *SD = &Config.cacheSwap.swapDirs[e->swap_dirn];
+    if (SD->bkgcheck)
+        return (SD->bkgcheck(SD, e));
+    else
+        return 0;
+}
+
+void
+storeBackgroundCheck(void *datanotused)
+{
+    static int bucketnum = -1;
+    static int validnum = 0;
+    static int store_errors = 0;
+    int validnum_start;
+    StoreEntry *e;
+    hash_link *link_ptr = NULL;
+    hash_link *link_next = NULL;
+    validnum_start = validnum;
+    while (validnum - validnum_start < Config.store_background_check_rate) {
+        if (++bucketnum >= store_hash_buckets) {
+            debug(20, 1) ("  Completed Background Check Loop\n");
+            debug(20, 1) ("  Rechecked %d Entries\n", validnum);
+            debug(20, 1) ("  store_swap_size = %dk\n", store_swap_size);
+            bucketnum = -1;
+            validnum = 0;
+            eventAdd("storeBackground", storeBackgroundCheck, NULL, 1.0, 1);
+            return;
+        }
+        link_next = hash_get_bucket(store_table, bucketnum);
+        while (NULL != (link_ptr = link_next)) {
+            link_next = link_ptr->next;
+            e = (StoreEntry *) link_ptr;
+            /* skip unvalidated entries */
+            if (!EBIT_TEST(e->flags, ENTRY_VALIDATED))
+                continue;
+            if (e->swap_filen < 0)
+                continue;
+            if (storeBackgroundCheckEntry(e)){
+                    store_errors++;
+                }
+#if 0
+            storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->swap_dirn], e->swap_file_sz, 1);
+#endif
+            if ((++validnum & 0x3FFFF) == 0)
+                debug(20, 1) ("  %7d Entries Validated so far.\n", validnum);
+        }
+    }
+    eventAdd("storeBackground", storeBackgroundCheck, NULL, 1.0, 1);
+}
+
 /* release an object from a cache */
 void
 storeRelease(StoreEntry * e)
Index: squid/src/store_rebuild.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_rebuild.c,v
retrieving revision 1.5
retrieving revision 1.5.6.1
diff -u -r1.5 -r1.5.6.1
--- squid/src/store_rebuild.c	10 Nov 2000 16:36:45 -0000	1.5
+++ squid/src/store_rebuild.c	25 Nov 2000 22:34:43 -0000	1.5.6.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_rebuild.c,v 1.5 2000/11/10 16:36:45 hno Exp $
+ * $Id: store_rebuild.c,v 1.5.6.1 2000/11/25 22:34:43 rbcollins Exp $
  *
  * DEBUG: section 20    Store Rebuild Routines
  * AUTHOR: Duane Wessels
@@ -74,10 +74,12 @@
 	    store_dirs_rebuilding--;
 	    assert(0 == store_dirs_rebuilding);
 	    if (opt_store_doublecheck != DBLCHECK_NONE)
-            /* we want to assert here because the storeFScode should auto-clean the entries */
+            /* we want to assert here because the doublecheck is for debugging
+             * storeFScode only. */
 		assert(store_errors == 0);
 	    if (store_digest)
 		storeDigestNoteStoreReady();
+            eventAdd("storeBackground", storeBackgroundCheck, NULL, 1.0, 1);
 	    return;
 	}
 	link_next = hash_get_bucket(store_table, bucketnum);
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.7
retrieving revision 1.7.4.1
diff -u -r1.7 -r1.7.4.1
--- squid/src/structs.h	14 Nov 2000 13:03:47 -0000	1.7
+++ squid/src/structs.h	25 Nov 2000 22:34:43 -0000	1.7.4.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.7 2000/11/14 13:03:47 adri Exp $
+ * $Id: structs.h,v 1.7.4.1 2000/11/25 22:34:43 rbcollins Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -515,6 +515,7 @@
 	size_t high_memory;
     } warnings;
     char *store_dir_select_algorithm;
+    int store_background_check_rate;
 };
 
 struct _SquidConfig2 {
@@ -1353,6 +1354,7 @@
     STDUMP *dump;		/* Dump fs config snippet */
     STFREE *freefs;		/* Free the fs data */
     STDBLCHECK *dblcheck;	/* Double check the obj integrity */
+    STDBLCHECK *bkgcheck;       /* Background check the obj integrity */
     STSTATFS *statfs;		/* Dump fs statistics */
     STMAINTAINFS *maintainfs;	/* Replacement maintainence */
     STCHECKOBJ *checkobj;	/* Check if the fs will store an object */
Index: squid/src/fs/aufs/store_dir_aufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fs/aufs/store_dir_aufs.c,v
retrieving revision 1.5
retrieving revision 1.5.6.1
diff -u -r1.5 -r1.5.6.1
--- squid/src/fs/aufs/store_dir_aufs.c	11 Nov 2000 09:40:02 -0000	1.5
+++ squid/src/fs/aufs/store_dir_aufs.c	25 Nov 2000 22:34:44 -0000	1.5.6.1
@@ -1686,6 +1686,7 @@
     sd->dump = storeAufsDirDump;
     sd->freefs = storeAufsDirFree;
     sd->dblcheck = storeAufsCleanupDoubleCheck;
+    sd->bkgcheck = NULL;
     sd->statfs = storeAufsDirStats;
     sd->maintainfs = storeAufsDirMaintain;
     sd->checkobj = storeAufsDirCheckObj;
Index: squid/src/fs/coss/store_dir_coss.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fs/coss/store_dir_coss.c,v
retrieving revision 1.3
retrieving revision 1.3.8.1
diff -u -r1.3 -r1.3.8.1
--- squid/src/fs/coss/store_dir_coss.c	3 Nov 2000 08:39:21 -0000	1.3
+++ squid/src/fs/coss/store_dir_coss.c	25 Nov 2000 22:34:44 -0000	1.3.8.1
@@ -732,6 +732,7 @@
     sd->dump = storeCossDirDump;
     sd->freefs = storeCossDirShutdown;
     sd->dblcheck = NULL;
+    sd->bkgcheck = NULL;
     sd->statfs = storeCossDirStats;
     sd->maintainfs = NULL;
     sd->checkobj = storeCossDirCheckObj;
Index: squid/src/fs/diskd/store_dir_diskd.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fs/diskd/store_dir_diskd.c,v
retrieving revision 1.4
retrieving revision 1.4.6.1
diff -u -r1.4 -r1.4.6.1
--- squid/src/fs/diskd/store_dir_diskd.c	10 Nov 2000 16:36:46 -0000	1.4
+++ squid/src/fs/diskd/store_dir_diskd.c	25 Nov 2000 22:34:45 -0000	1.4.6.1
@@ -1937,6 +1937,7 @@
     sd->dump = storeDiskdDirDump;
     sd->freefs = storeDiskdDirFree;
     sd->dblcheck = storeDiskdCleanupDoubleCheck;
+    sd->bkgcheck = NULL;
     sd->statfs = storeDiskdDirStats;
     sd->maintainfs = storeDiskdDirMaintain;
     sd->checkobj = storeDiskdDirCheckObj;
Index: squid/src/fs/ufs/store_dir_ufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fs/ufs/store_dir_ufs.c,v
retrieving revision 1.4
retrieving revision 1.4.6.1
diff -u -r1.4 -r1.4.6.1
--- squid/src/fs/ufs/store_dir_ufs.c	10 Nov 2000 16:36:47 -0000	1.4
+++ squid/src/fs/ufs/store_dir_ufs.c	25 Nov 2000 22:34:46 -0000	1.4.6.1
@@ -117,7 +117,8 @@
 static int storeUfsDirIs(SwapDir * sd);
 static int storeUfsFilenoBelongsHere(int fn, int F0, int F1, int F2);
 static int storeUfsCleanupDoubleCheck(SwapDir *, StoreEntry *);
-static int storeUfsCheckFile(SwapDir * sd, sfileno filn, size_t swap_file_sz );
+static int storeUfsBackgroundCheck(SwapDir  * sd, StoreEntry * e);
+static int storeUfsCheckFile(SwapDir * sd, sfileno filn, size_t swap_file_sz, int debuglevel );
 static void storeUfsDirStats(SwapDir *, StoreEntry *);
 static void storeUfsDirInitBitmap(SwapDir *);
 static int storeUfsDirValidFileno(SwapDir *, sfileno, int);
@@ -524,7 +525,6 @@
     int count;
     int used;			/* is swapfile already in use? */
     int disk_entry_newer;	/* is the log entry newer than current entry? */
-    int file_bad;
     double x;
     assert(rb != NULL);
     /* load a number of objects per invocation */
@@ -610,21 +610,7 @@
 	 * appear to have a newer entry?  Compare 'lastref' from the
 	 * swap log to e->lastref. */
 	disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;
-        if (!used && (rb->flags.need_to_validate ||
-            (opt_store_doublecheck != DBLCHECK_NONE))){
-            file_bad = storeUfsCheckFile(SD, s.swap_filen, s.swap_file_sz);
-        } else 
-            file_bad = 0;
-        if (file_bad){
-            if (file_bad==-2){
-                  if (opt_store_doublecheck == DBLCHECK_FORCE) 
-                      storeUfsDirUnlinkFile(SD, s.swap_filen);
-                  rb->counts.filesizemismatchcount++; 
-                  continue;
-            }
-            rb->counts.missingcount++;
-            continue;
-	}else if (used && !disk_entry_newer) {
+	if (used && !disk_entry_newer) {
 	    /* log entry is old, ignore it */
 	    rb->counts.clashcount++;
 	    continue;
@@ -1591,33 +1577,58 @@
 static int
 storeUfsCleanupDoubleCheck(SwapDir * sd, StoreEntry * e)
 {
-    int rv= storeUfsCheckFile(sd, e->swap_filen, e->swap_file_sz);
+    int rv= storeUfsCheckFile(sd, e->swap_filen, e->swap_file_sz, 1);
     if (rv) storeEntryDump(e, 0);
     return rv;
 }
 
+/* 
+ * storeUfsBackgroundCheck
+ *
+ * This is called by storeBackgroundCheck() to perform background consistency
+ * checking.
+ */
+static int 
+storeUfsBackgroundCheck(SwapDir  * sd, StoreEntry * e)
+{
+    int rv;
+    /* we shouldn't be called until the rebuild finishes... but who knows? */
+    if (store_dirs_rebuilding) 
+        return 0;
+    rv = storeUfsCheckFile(sd, e->swap_filen, e->swap_file_sz, 1);
+    
+    if (rv) {
+        /* the file is faulty - missing or has a size mismatch from the 
+         * in-memory swap.state */
+        storeRelease(e);
+    }
+    return rv;
+}
+
+
+
 /*
  * storeUfsCheckFile
  *
  * This is called by storerebuildFromSwapLog if -S was given on the command line. or a Dirty state is found
  */
 static int
-storeUfsCheckFile(SwapDir * sd, sfileno filen, size_t swap_file_sz )
+storeUfsCheckFile(SwapDir * sd, sfileno filen, size_t swap_file_sz , int debuglevel)
 {
     struct stat sb;
 
     if (stat(storeUfsDirFullPath(sd, filen, NULL), &sb) < 0) {
-        debug(20, 1) ("storeUfsCheckFile: MISSING SWAP FILE\n");
-        debug(20, 1) ("storeUfsCheckFile: FILENO %08X\n", filen);
-        debug(20, 1) ("storeUfsCheckFile: PATH %s\n", storeUfsDirFullPath(sd, filen, NULL));
+        debug(20, debuglevel) ("storeUfsCheckFile: MISSING SWAP FILE\n");
+        debug(20, debuglevel) ("storeUfsCheckFile: FILENO %08X\n", filen);
+        debug(20, debuglevel) ("storeUfsCheckFile: PATH %s\n", storeUfsDirFullPath(sd, filen, NULL));
 
         return -1;
     }
     if (swap_file_sz != sb.st_size) {
-        debug(20, 1) ("storeUfsCheckFile: SIZE MISMATCH\n");
-        debug(20, 1) ("storeUfsCheckFile: FILENO %08X\n", filen);
-        debug(20, 1) ("storeUfsCheckFile: PATH %s\n", storeUfsDirFullPath(sd, filen, NULL));
-        debug(20, 1) ("storeUfsCheckFile: ENTRY SIZE: %d, FILE SIZE: %d\n", swap_file_sz, (int) sb.st_size);
+        debug(20, debuglevel) ("storeUfsCheckFile: SIZE MISMATCH\n");
+        debug(20, debuglevel) ("storeUfsCheckFile: FILENO %08X\n", filen);
+        debug(20, debuglevel) ("storeUfsCheckFile: PATH %s\n", storeUfsDirFullPath(sd, filen, NULL));
+        debug(20, debuglevel) ("storeUfsCheckFile: ENTRY SIZE: %d, FILE SIZE: %d\n", swap_file_sz, (int) sb.st_size);
         return -2;
     }
     return 0;
@@ -1676,6 +1687,7 @@
     sd->dump = storeUfsDirDump;
     sd->freefs = storeUfsDirFree;
     sd->dblcheck = storeUfsCleanupDoubleCheck;
+    sd->bkgcheck = storeUfsBackgroundCheck;
     sd->statfs = storeUfsDirStats;
     sd->maintainfs = storeUfsDirMaintain;
     sd->checkobj = storeUfsDirCheckObj;
