Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "stdinc.h"
#include "dat.h"
#include "fns.h"

uchar buf[64*1024];

void
usage(void)
{
        fprint(2, "usage: printarenapart arenafile [offset]\n");
        threadexitsall("usage");
}

static void
rdarena(Arena *arena, u64int offset)
{
        u64int a, aa, e;
        u32int magic;
        Clump cl;
        uchar score[VtScoreSize];
        ZBlock *lump;

        printarena(2, arena);

        a = arena->base;
        e = arena->base + arena->size;
        if(offset != ~(u64int)0) {
                if(offset >= e-a)
                        sysfatal("bad offset %llud >= %llud",
                                offset, e-a);
                aa = offset;
        } else
                aa = 0;

        for(; aa < e; aa += ClumpSize+cl.info.size) {
                magic = clumpmagic(arena, aa);
                if(magic == ClumpFreeMagic)
                        break;
                if(magic != arena->clumpmagic) {
                        fprint(2, "illegal clump magic number %#8.8ux offset %llud\n",
                                magic, aa);
                        break;
                }
                lump = loadclump(arena, aa, 0, &cl, score, 0);
                if(lump == nil) {
                        fprint(2, "clump %llud failed to read: %r\n", aa);
                        break;
                }
                if(cl.info.type != VtCorruptType) {
                        scoremem(score, lump->data, cl.info.uncsize);
                        if(scorecmp(cl.info.score, score) != 0) {
                                fprint(2, "clump %llud has mismatched score\n", aa);
                                break;
                        }
                        if(vttypevalid(cl.info.type) < 0) {
                                fprint(2, "clump %llud has bad type %d\n", aa, cl.info.type);
                                break;
                        }
                }
                print("%22llud %V %3d %5d\n", aa, score, cl.info.type, cl.info.uncsize);
                freezblock(lump);
        }
        print("end offset %llud\n", aa);
}

void
threadmain(int argc, char *argv[])
{
        char *file, *p, *name;
        char *table;
        u64int offset;
        Part *part;
        ArenaPart ap;
        ArenaHead head;
        Arena tail;
        char ct[40], mt[40];

        readonly = 1;   /* for part.c */
        ARGBEGIN{
        default:
                usage();
                break;
        }ARGEND

        switch(argc) {
        default:
                usage();
        case 1:
                file = argv[0];
        }

        ventifmtinstall();
        statsinit();

        part = initpart(file, OREAD|ODIRECT);
        if(part == nil)
                sysfatal("can't open file %s: %r", file);
        if(readpart(part, PartBlank, buf, sizeof buf) < 0)
                sysfatal("can't read file %s: %r", file);

        if(unpackarenapart(&ap, buf) < 0)
                sysfatal("corrupted arena part header: %r");

        print("# arena part version=%d blocksize=%d arenabase=%d\n",
                ap.version, ap.blocksize, ap.arenabase);
        ap.tabbase = (PartBlank+HeadSize+ap.blocksize-1)&~(ap.blocksize-1);
        ap.tabsize = ap.arenabase - ap.tabbase;

        table = malloc(ap.tabsize+1);
        if(readpart(part, ap.tabbase, (uchar*)table, ap.tabsize) < 0)
                sysfatal("read %s: %r", file);
        table[ap.tabsize] = 0;

        partblocksize(part, ap.blocksize);
        initdcache(8 * MaxDiskBlock);

        for(p=table; p && *p; p=strchr(p, '\n')){
                if(*p == '\n')
                        p++;
                name = p;
                p = strpbrk(p, " \t");
                if(p == nil){
                        fprint(2, "bad line: %s\n", name);
                        break;
                }
                offset = strtoull(p, nil, 0);
                if(readpart(part, offset, buf, sizeof buf) < 0){
                        fprint(2, "%s: read %s: %r\n", argv0, file);
                        continue;
                }
                if(unpackarenahead(&head, buf) < 0){
                        fprint(2, "%s: unpackarenahead: %r\n", argv0);
                        continue;
                }
                if(readpart(part, offset+head.size-head.blocksize, buf, head.blocksize) < 0){
                        fprint(2, "%s: read %s: %r\n", argv0, file);
                        continue;
                }
                if(unpackarena(&tail, buf) < 0){
                        fprint(2, "%s: unpackarena: %r\n", argv0);
                        continue;
                }
                print("arena %s %lld clumps=%,d cclumps=%,d used=%,lld uncsize=%,lld%s\n",
                        tail.name, offset,
                        tail.diskstats.clumps, tail.diskstats.cclumps,
                        tail.diskstats.used, tail.diskstats.uncsize,
                        tail.diskstats.sealed ? " sealed" : "");
                strcpy(ct, ctime(tail.ctime));
                ct[28] = 0;
                strcpy(mt, ctime(tail.wtime));
                mt[28] = 0;
                print("\tctime=%s\n\tmtime=%s\n", ct, mt);
        }
        threadexitsall(0);
}