--------------------- 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;