Blob


1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
5 char *host;
6 int readonly = 1; /* for part.c */
8 void
9 usage(void)
10 {
11 fprint(2, "usage: wrarena [-h host] arenafile [offset]\n");
12 threadexitsall("usage");
13 }
15 static void
16 rdarena(VtConn *z, Arena *arena, u64int offset)
17 {
18 u64int a, aa, e;
19 u32int magic;
20 Clump cl;
21 uchar score[VtScoreSize];
22 ZBlock *lump;
24 fprint(2, "copying %s to venti\n", arena->name);
25 printarena(2, arena);
27 a = arena->base;
28 e = arena->base + arena->size;
29 if(offset != ~(u64int)0) {
30 if(offset >= e-a)
31 sysfatal("bad offset %llud >= %llud\n",
32 offset, e-a);
33 aa = offset;
34 } else
35 aa = 0;
37 for(; aa < e; aa += ClumpSize+cl.info.size) {
38 magic = clumpmagic(arena, aa);
39 if(magic == ClumpFreeMagic)
40 break;
41 if(magic != ClumpMagic) {
42 fprint(2, "illegal clump magic number %#8.8ux offset %llud\n",
43 magic, aa);
44 break;
45 }
46 lump = loadclump(arena, aa, 0, &cl, score, 0);
47 if(lump == nil) {
48 fprint(2, "clump %llud failed to read: %r\n", aa);
49 break;
50 }
51 if(cl.info.type != VtTypeCorrupt) {
52 scoremem(score, lump->data, cl.info.uncsize);
53 if(scorecmp(cl.info.score, score) != 0) {
54 fprint(2, "clump %llud has mismatched score\n", aa);
55 break;
56 }
57 if(vttypevalid(cl.info.type) < 0) {
58 fprint(2, "clump %llud has bad type %d\n", aa, cl.info.type);
59 break;
60 }
61 }
62 if(z && vtwrite(z, score, cl.info.type, lump->data, cl.info.uncsize) < 0)
63 sysfatal("failed writing clump %llud: %r", aa);
64 freezblock(lump);
65 }
66 if(z && vtsync(z) < 0)
67 sysfatal("failed executing sync: %r");
69 print("end offset %llud\n", aa);
70 }
72 void
73 threadmain(int argc, char *argv[])
74 {
75 char *file;
76 VtConn *z;
77 Arena *arena;
78 u64int offset, aoffset;
79 Part *part;
80 Dir *d;
81 uchar buf[8192];
82 ArenaHead head;
84 aoffset = 0;
85 ARGBEGIN{
86 case 'h':
87 host = EARGF(usage());
88 break;
89 case 'o':
90 aoffset = strtoull(EARGF(usage()), 0, 0);
91 break;
92 default:
93 usage();
94 break;
95 }ARGEND
97 offset = ~(u64int)0;
98 switch(argc) {
99 default:
100 usage();
101 case 2:
102 offset = strtoull(argv[1], 0, 0);
103 /* fall through */
104 case 1:
105 file = argv[0];
109 fmtinstall('V', vtscorefmt);
111 statsinit();
113 if((d = dirstat(file)) == nil)
114 sysfatal("can't stat file %s: %r", file);
116 part = initpart(file, 0);
117 if(part == nil)
118 sysfatal("can't open file %s: %r", file);
119 if(readpart(part, aoffset, buf, sizeof buf) < 0)
120 sysfatal("can't read file %s: %r", file);
122 if(unpackarenahead(&head, buf) < 0)
123 sysfatal("corrupted arena header: %r");
125 if(aoffset+head.size > d->length)
126 sysfatal("arena is truncated: want %llud bytes have %llud\n",
127 head.size, d->length);
129 partblocksize(part, head.blocksize);
130 initdcache(8 * MaxDiskBlock);
132 arena = initarena(part, aoffset, head.size, head.blocksize);
133 if(arena == nil)
134 sysfatal("initarena: %r");
136 if(host && strcmp(host, "/dev/null") != 0){
137 z = vtdial(host);
138 if(z == nil)
139 sysfatal("could not connect to server: %r");
140 if(vtconnect(z) < 0)
141 sysfatal("vtconnect: %r");
142 }else
143 z = nil;
145 rdarena(z, arena, offset);
146 vthangup(z);
147 threadexitsall(0);