diff options
Diffstat (limited to 'src/cmd/venti/srv/rdarena.c')
-rw-r--r-- | src/cmd/venti/srv/rdarena.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/cmd/venti/srv/rdarena.c b/src/cmd/venti/srv/rdarena.c new file mode 100644 index 00000000..909cc206 --- /dev/null +++ b/src/cmd/venti/srv/rdarena.c @@ -0,0 +1,91 @@ +#include "stdinc.h" +#include "dat.h" +#include "fns.h" + +static int verbose; + +void +usage(void) +{ + fprint(2, "usage: rdarena [-v] arenapart arena\n"); + threadexitsall(0); +} + +static void +rdarena(Arena *arena) +{ + ZBlock *b; + u64int a, e; + u32int bs; + + fprint(2, "copying %s to standard output\n", arena->name); + printarena(2, arena); + + bs = MaxIoSize; + if(bs < arena->blocksize) + bs = arena->blocksize; + + b = alloczblock(bs, 0, arena->blocksize); + e = arena->base + arena->size + arena->blocksize; + for(a = arena->base - arena->blocksize; a + arena->blocksize <= e; a += bs){ + if(a + bs > e) + bs = arena->blocksize; + if(readpart(arena->part, a, b->data, bs) < 0) + fprint(2, "can't copy %s, read at %lld failed: %r\n", arena->name, a); + if(write(1, b->data, bs) != bs) + sysfatal("can't copy %s, write at %lld failed: %r", arena->name, a); + } + + freezblock(b); +} + +void +threadmain(int argc, char *argv[]) +{ + ArenaPart *ap; + Part *part; + char *file, *aname; + int i; + + ventifmtinstall(); + statsinit(); + + ARGBEGIN{ + case 'v': + verbose++; + break; + default: + usage(); + break; + }ARGEND + + readonly = 1; + + if(argc != 2) + usage(); + + file = argv[0]; + aname = argv[1]; + + part = initpart(file, OREAD|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) + printarenapart(2, ap); + + initdcache(8 * MaxDiskBlock); + + for(i = 0; i < ap->narenas; i++){ + if(strcmp(ap->arenas[i]->name, aname) == 0){ + rdarena(ap->arenas[i]); + threadexitsall(0); + } + } + + sysfatal("couldn't find arena %s\n", aname); +} |