diff options
author | rsc <devnull@localhost> | 2005-07-12 15:23:36 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-07-12 15:23:36 +0000 |
commit | a0d146edd7a7de6236a0d60baafeeb59f8452aae (patch) | |
tree | b55baa526d9f5adfc73246e6ee2fadf455e0b7a2 /src/cmd/venti/srv/checkarenas.c | |
parent | 88bb285e3d87ec2508840af33f7e0af53ec3c13c (diff) | |
download | plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.gz plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.bz2 plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.zip |
return of venti
Diffstat (limited to 'src/cmd/venti/srv/checkarenas.c')
-rw-r--r-- | src/cmd/venti/srv/checkarenas.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/cmd/venti/srv/checkarenas.c b/src/cmd/venti/srv/checkarenas.c new file mode 100644 index 00000000..525a634c --- /dev/null +++ b/src/cmd/venti/srv/checkarenas.c @@ -0,0 +1,135 @@ +#include "stdinc.h" +#include "dat.h" +#include "fns.h" + +static int verbose; + +static void +checkarena(Arena *arena, int scan, int fix) +{ + ATailStats old; + int err, e; + + if(verbose && arena->memstats.clumps) + printarena(2, arena); + + old = arena->memstats; + + if(scan){ + arena->memstats.used = 0; + arena->memstats.clumps = 0; + arena->memstats.cclumps = 0; + arena->memstats.uncsize = 0; + } + + err = 0; + for(;;){ + e = syncarena(arena, 0, 1000, 0, fix); + err |= e; + if(!(e & SyncHeader)) + break; + if(verbose && arena->memstats.clumps) + fprint(2, "."); + } + if(verbose && arena->memstats.clumps) + fprint(2, "\n"); + + err &= ~SyncHeader; + if(arena->memstats.used != old.used + || arena->memstats.clumps != old.clumps + || arena->memstats.cclumps != old.cclumps + || arena->memstats.uncsize != old.uncsize){ + fprint(2, "%s: incorrect arena header fields\n", arena->name); + printarena(2, arena); + err |= SyncHeader; + } + + if(!err || !fix) + return; + + fprint(2, "%s: writing fixed arena header fields\n", arena->name); + arena->diskstats = arena->memstats; + if(wbarena(arena) < 0) + fprint(2, "arena header write failed: %r\n"); + flushdcache(); +} + +void +usage(void) +{ + fprint(2, "usage: checkarenas [-afv] file [arenaname...]\n"); + threadexitsall(0); +} + +int +should(char *name, int argc, char **argv) +{ + int i; + + if(argc == 0) + return 1; + for(i=0; i<argc; i++) + if(strcmp(name, argv[i]) == 0) + return 1; + return 0; +} + +void +threadmain(int argc, char *argv[]) +{ + ArenaPart *ap; + Part *part; + char *file; + int i, fix, scan; + + ventifmtinstall(); + statsinit(); + + fix = 0; + scan = 0; + ARGBEGIN{ + case 'f': + fix++; + break; + case 'a': + scan = 1; + break; + case 'v': + verbose++; + break; + default: + usage(); + break; + }ARGEND + + if(!fix) + readonly = 1; + + if(argc < 1) + usage(); + + file = argv[0]; + + part = initpart(file, ORDWR|ODIRECT); + if(part == nil) + sysfatal("can't open partition %s: %r", file); + + ap = initarenapart(part); + if(ap == nil) + sysfatal("can't initialize arena partition in %s: %r", file); + + if(verbose > 1){ + printarenapart(2, ap); + fprint(2, "\n"); + } + + initdcache(8 * MaxDiskBlock); + + for(i = 0; i < ap->narenas; i++) + if(should(ap->arenas[i]->name, argc, argv)) + checkarena(ap->arenas[i], scan, fix); + + if(verbose > 1) + printstats(); + threadexitsall(0); +} |