xref: /plan9/sys/src/cmd/venti/srv/printarena.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
4 
5 void
usage(void)6 usage(void)
7 {
8 	fprint(2, "usage: printarena arenafile [offset]\n");
9 	threadexitsall("usage");
10 }
11 
12 static void
rdarena(Arena * arena,u64int offset)13 rdarena(Arena *arena, u64int offset)
14 {
15 	u64int a, aa, e;
16 	u32int magic;
17 	Clump cl;
18 	uchar score[VtScoreSize];
19 	ZBlock *lump;
20 
21 	printarena(2, arena);
22 
23 	a = arena->base;
24 	e = arena->base + arena->size;
25 	if(offset != ~(u64int)0) {
26 		if(offset >= e-a)
27 			sysfatal("bad offset %llud >= %llud",
28 				offset, e-a);
29 		aa = offset;
30 	} else
31 		aa = 0;
32 
33 	for(; aa < e; aa += ClumpSize+cl.info.size) {
34 		magic = clumpmagic(arena, aa);
35 		if(magic == ClumpFreeMagic)
36 			break;
37 		if(magic != arena->clumpmagic) {
38 			fprint(2, "illegal clump magic number %#8.8ux offset %llud\n",
39 				magic, aa);
40 			break;
41 		}
42 		lump = loadclump(arena, aa, 0, &cl, score, 0);
43 		if(lump == nil) {
44 			fprint(2, "clump %llud failed to read: %r\n", aa);
45 			break;
46 		}
47 		if(cl.info.type != VtCorruptType) {
48 			scoremem(score, lump->data, cl.info.uncsize);
49 			if(scorecmp(cl.info.score, score) != 0) {
50 				fprint(2, "clump %llud has mismatched score\n", aa);
51 				break;
52 			}
53 			if(vttypevalid(cl.info.type) < 0) {
54 				fprint(2, "clump %llud has bad type %d\n", aa, cl.info.type);
55 				break;
56 			}
57 		}
58 		print("%22llud %V %3d %5d\n", aa, score, cl.info.type, cl.info.uncsize);
59 		freezblock(lump);
60 	}
61 	print("end offset %llud\n", aa);
62 }
63 
64 void
threadmain(int argc,char * argv[])65 threadmain(int argc, char *argv[])
66 {
67 	char *file;
68 	Arena *arena;
69 	u64int offset, aoffset;
70 	Part *part;
71 	static uchar buf[8192];
72 	ArenaHead head;
73 
74 	readonly = 1;	/* for part.c */
75 	aoffset = 0;
76 	ARGBEGIN{
77 	case 'o':
78 		aoffset = strtoull(EARGF(usage()), 0, 0);
79 		break;
80 	default:
81 		usage();
82 		break;
83 	}ARGEND
84 
85 	offset = ~(u64int)0;
86 	switch(argc) {
87 	default:
88 		usage();
89 	case 2:
90 		offset = strtoull(argv[1], 0, 0);
91 		/* fall through */
92 	case 1:
93 		file = argv[0];
94 	}
95 
96 
97 	ventifmtinstall();
98 	statsinit();
99 
100 	part = initpart(file, OREAD|ODIRECT);
101 	if(part == nil)
102 		sysfatal("can't open file %s: %r", file);
103 	if(readpart(part, aoffset, buf, sizeof buf) < 0)
104 		sysfatal("can't read file %s: %r", file);
105 
106 	if(unpackarenahead(&head, buf) < 0)
107 		sysfatal("corrupted arena header: %r");
108 
109 	print("# arena head version=%d name=%.*s blocksize=%d size=%lld clumpmagic=0x%.8ux\n",
110 		head.version, ANameSize, head.name, head.blocksize,
111 		head.size, head.clumpmagic);
112 
113 	if(aoffset+head.size > part->size)
114 		sysfatal("arena is truncated: want %llud bytes have %llud",
115 			head.size, part->size);
116 
117 	partblocksize(part, head.blocksize);
118 	initdcache(8 * MaxDiskBlock);
119 
120 	arena = initarena(part, aoffset, head.size, head.blocksize);
121 	if(arena == nil)
122 		sysfatal("initarena: %r");
123 
124 	rdarena(arena, offset);
125 	threadexitsall(0);
126 }
127