checkarenas.c (2335B)
1 #include "stdinc.h" 2 #include "dat.h" 3 #include "fns.h" 4 5 static int verbose; 6 7 static void 8 checkarena(Arena *arena, int scan, int fix) 9 { 10 ATailStats old; 11 int err, e; 12 13 if(verbose && arena->memstats.clumps) 14 printarena(2, arena); 15 16 old = arena->memstats; 17 18 if(scan){ 19 arena->memstats.used = 0; 20 arena->memstats.clumps = 0; 21 arena->memstats.cclumps = 0; 22 arena->memstats.uncsize = 0; 23 } 24 25 err = 0; 26 for(;;){ 27 e = syncarena(arena, 1000, 0, fix); 28 err |= e; 29 if(!(e & SyncHeader)) 30 break; 31 if(verbose && arena->memstats.clumps) 32 fprint(2, "."); 33 } 34 if(verbose && arena->memstats.clumps) 35 fprint(2, "\n"); 36 37 err &= ~SyncHeader; 38 if(arena->memstats.used != old.used 39 || arena->memstats.clumps != old.clumps 40 || arena->memstats.cclumps != old.cclumps 41 || arena->memstats.uncsize != old.uncsize){ 42 fprint(2, "%s: incorrect arena header fields\n", arena->name); 43 printarena(2, arena); 44 err |= SyncHeader; 45 } 46 47 if(!err || !fix) 48 return; 49 50 fprint(2, "%s: writing fixed arena header fields\n", arena->name); 51 arena->diskstats = arena->memstats; 52 if(wbarena(arena) < 0) 53 fprint(2, "arena header write failed: %r\n"); 54 flushdcache(); 55 } 56 57 void 58 usage(void) 59 { 60 fprint(2, "usage: checkarenas [-afv] file [arenaname...]\n"); 61 threadexitsall(0); 62 } 63 64 int 65 should(char *name, int argc, char **argv) 66 { 67 int i; 68 69 if(argc == 0) 70 return 1; 71 for(i=0; i<argc; i++) 72 if(strcmp(name, argv[i]) == 0) 73 return 1; 74 return 0; 75 } 76 77 void 78 threadmain(int argc, char *argv[]) 79 { 80 ArenaPart *ap; 81 Part *part; 82 char *file; 83 int i, fix, scan; 84 85 ventifmtinstall(); 86 statsinit(); 87 88 fix = 0; 89 scan = 0; 90 ARGBEGIN{ 91 case 'f': 92 fix++; 93 break; 94 case 'a': 95 scan = 1; 96 break; 97 case 'v': 98 verbose++; 99 break; 100 default: 101 usage(); 102 break; 103 }ARGEND 104 105 if(!fix) 106 readonly = 1; 107 108 if(argc < 1) 109 usage(); 110 111 file = argv[0]; 112 argc--; 113 argv++; 114 115 part = initpart(file, (fix ? ORDWR : OREAD)|ODIRECT); 116 if(part == nil) 117 sysfatal("can't open partition %s: %r", file); 118 119 ap = initarenapart(part); 120 if(ap == nil) 121 sysfatal("can't initialize arena partition in %s: %r", file); 122 123 if(verbose > 1){ 124 printarenapart(2, ap); 125 fprint(2, "\n"); 126 } 127 128 initdcache(8 * MaxDiskBlock); 129 130 for(i = 0; i < ap->narenas; i++) 131 if(should(ap->arenas[i]->name, argc, argv)) { 132 debugarena = i; 133 checkarena(ap->arenas[i], scan, fix); 134 } 135 136 if(verbose > 1) 137 printstats(); 138 threadexitsall(0); 139 }