Blame


1 a0d146ed 2005-07-12 devnull #include "stdinc.h"
2 a0d146ed 2005-07-12 devnull #include "dat.h"
3 a0d146ed 2005-07-12 devnull #include "fns.h"
4 a0d146ed 2005-07-12 devnull
5 a0d146ed 2005-07-12 devnull QLock godot;
6 a0d146ed 2005-07-12 devnull char *host;
7 a0d146ed 2005-07-12 devnull int readonly = 1; /* for part.c */
8 a0d146ed 2005-07-12 devnull int mainstacksize = 256*1024;
9 a0d146ed 2005-07-12 devnull Channel *c;
10 a0d146ed 2005-07-12 devnull VtConn *z;
11 a0d146ed 2005-07-12 devnull int fast; /* and a bit unsafe; only for benchmarking */
12 a0d146ed 2005-07-12 devnull int haveaoffset;
13 a0d146ed 2005-07-12 devnull int maxwrites = -1;
14 a0d146ed 2005-07-12 devnull
15 a0d146ed 2005-07-12 devnull typedef struct ZClump ZClump;
16 a0d146ed 2005-07-12 devnull struct ZClump
17 a0d146ed 2005-07-12 devnull {
18 a0d146ed 2005-07-12 devnull ZBlock *lump;
19 a0d146ed 2005-07-12 devnull Clump cl;
20 a0d146ed 2005-07-12 devnull u64int aa;
21 a0d146ed 2005-07-12 devnull };
22 a0d146ed 2005-07-12 devnull
23 a0d146ed 2005-07-12 devnull void
24 a0d146ed 2005-07-12 devnull usage(void)
25 a0d146ed 2005-07-12 devnull {
26 a0d146ed 2005-07-12 devnull fprint(2, "usage: wrarena [-h host] arenafile [offset]\n");
27 a0d146ed 2005-07-12 devnull threadexitsall("usage");
28 a0d146ed 2005-07-12 devnull }
29 a0d146ed 2005-07-12 devnull
30 a0d146ed 2005-07-12 devnull void
31 a0d146ed 2005-07-12 devnull vtsendthread(void *v)
32 a0d146ed 2005-07-12 devnull {
33 a0d146ed 2005-07-12 devnull ZClump zcl;
34 a0d146ed 2005-07-12 devnull
35 a0d146ed 2005-07-12 devnull USED(v);
36 a0d146ed 2005-07-12 devnull while(recv(c, &zcl) == 1){
37 a0d146ed 2005-07-12 devnull if(zcl.lump == nil)
38 a0d146ed 2005-07-12 devnull break;
39 a0d146ed 2005-07-12 devnull if(vtwrite(z, zcl.cl.info.score, zcl.cl.info.type, zcl.lump->data, zcl.cl.info.uncsize) < 0)
40 a0d146ed 2005-07-12 devnull sysfatal("failed writing clump %llud: %r", zcl.aa);
41 a0d146ed 2005-07-12 devnull freezblock(zcl.lump);
42 a0d146ed 2005-07-12 devnull }
43 a0d146ed 2005-07-12 devnull /*
44 a0d146ed 2005-07-12 devnull * All the send threads try to exit right when
45 a0d146ed 2005-07-12 devnull * threadmain is calling threadexitsall.
46 a0d146ed 2005-07-12 devnull * Either libthread or the Linux NPTL pthreads library
47 a0d146ed 2005-07-12 devnull * can't handle this condition (I suspect NPTL but have
48 a0d146ed 2005-07-12 devnull * not confirmed this) and we get a seg fault in exit.
49 a0d146ed 2005-07-12 devnull * I spent a day tracking this down with no success,
50 a0d146ed 2005-07-12 devnull * so we're going to work around it instead by just
51 a0d146ed 2005-07-12 devnull * sitting here and waiting for the threadexitsall to
52 a0d146ed 2005-07-12 devnull * take effect.
53 a0d146ed 2005-07-12 devnull */
54 a0d146ed 2005-07-12 devnull qlock(&godot);
55 a0d146ed 2005-07-12 devnull }
56 a0d146ed 2005-07-12 devnull
57 a0d146ed 2005-07-12 devnull static void
58 a0d146ed 2005-07-12 devnull rdarena(Arena *arena, u64int offset)
59 a0d146ed 2005-07-12 devnull {
60 a0d146ed 2005-07-12 devnull u64int a, aa, e;
61 a0d146ed 2005-07-12 devnull u32int magic;
62 a0d146ed 2005-07-12 devnull Clump cl;
63 a0d146ed 2005-07-12 devnull uchar score[VtScoreSize];
64 a0d146ed 2005-07-12 devnull ZBlock *lump;
65 a0d146ed 2005-07-12 devnull ZClump zcl;
66 a0d146ed 2005-07-12 devnull
67 a0d146ed 2005-07-12 devnull fprint(2, "wrarena: copying %s to venti\n", arena->name);
68 a0d146ed 2005-07-12 devnull printarena(2, arena);
69 a0d146ed 2005-07-12 devnull
70 a0d146ed 2005-07-12 devnull a = arena->base;
71 a0d146ed 2005-07-12 devnull e = arena->base + arena->size;
72 a0d146ed 2005-07-12 devnull if(offset != ~(u64int)0) {
73 a0d146ed 2005-07-12 devnull if(offset >= e-a)
74 a0d146ed 2005-07-12 devnull sysfatal("bad offset %llud >= %llud\n",
75 a0d146ed 2005-07-12 devnull offset, e-a);
76 a0d146ed 2005-07-12 devnull aa = offset;
77 a0d146ed 2005-07-12 devnull } else
78 a0d146ed 2005-07-12 devnull aa = 0;
79 a0d146ed 2005-07-12 devnull
80 a0d146ed 2005-07-12 devnull if(maxwrites != 0)
81 a0d146ed 2005-07-12 devnull for(; aa < e; aa += ClumpSize+cl.info.size) {
82 a0d146ed 2005-07-12 devnull magic = clumpmagic(arena, aa);
83 a0d146ed 2005-07-12 devnull if(magic == ClumpFreeMagic)
84 a0d146ed 2005-07-12 devnull break;
85 a0d146ed 2005-07-12 devnull if(magic != arena->clumpmagic) {
86 a0d146ed 2005-07-12 devnull // fprint(2, "illegal clump magic number %#8.8ux offset %llud\n",
87 a0d146ed 2005-07-12 devnull // magic, aa);
88 a0d146ed 2005-07-12 devnull break;
89 a0d146ed 2005-07-12 devnull }
90 a0d146ed 2005-07-12 devnull lump = loadclump(arena, aa, 0, &cl, score, 0);
91 a0d146ed 2005-07-12 devnull if(lump == nil) {
92 a0d146ed 2005-07-12 devnull fprint(2, "clump %llud failed to read: %r\n", aa);
93 a0d146ed 2005-07-12 devnull break;
94 a0d146ed 2005-07-12 devnull }
95 a0d146ed 2005-07-12 devnull if(!fast && cl.info.type != VtCorruptType) {
96 a0d146ed 2005-07-12 devnull scoremem(score, lump->data, cl.info.uncsize);
97 a0d146ed 2005-07-12 devnull if(scorecmp(cl.info.score, score) != 0) {
98 a0d146ed 2005-07-12 devnull fprint(2, "clump %llud has mismatched score\n", aa);
99 a0d146ed 2005-07-12 devnull break;
100 a0d146ed 2005-07-12 devnull }
101 a0d146ed 2005-07-12 devnull if(vttypevalid(cl.info.type) < 0) {
102 a0d146ed 2005-07-12 devnull fprint(2, "clump %llud has bad type %d\n", aa, cl.info.type);
103 a0d146ed 2005-07-12 devnull break;
104 a0d146ed 2005-07-12 devnull }
105 a0d146ed 2005-07-12 devnull }
106 a0d146ed 2005-07-12 devnull if(z && cl.info.type != VtCorruptType){
107 a0d146ed 2005-07-12 devnull zcl.cl = cl;
108 a0d146ed 2005-07-12 devnull zcl.lump = lump;
109 a0d146ed 2005-07-12 devnull zcl.aa = aa;
110 a0d146ed 2005-07-12 devnull send(c, &zcl);
111 a0d146ed 2005-07-12 devnull }else
112 a0d146ed 2005-07-12 devnull freezblock(lump);
113 a0d146ed 2005-07-12 devnull if(maxwrites>0 && --maxwrites == 0)
114 a0d146ed 2005-07-12 devnull break;
115 a0d146ed 2005-07-12 devnull }
116 a0d146ed 2005-07-12 devnull if(haveaoffset)
117 a0d146ed 2005-07-12 devnull print("end offset %llud\n", aa);
118 a0d146ed 2005-07-12 devnull }
119 a0d146ed 2005-07-12 devnull
120 a0d146ed 2005-07-12 devnull void
121 a0d146ed 2005-07-12 devnull threadmain(int argc, char *argv[])
122 a0d146ed 2005-07-12 devnull {
123 a0d146ed 2005-07-12 devnull int i;
124 a0d146ed 2005-07-12 devnull char *file;
125 a0d146ed 2005-07-12 devnull Arena *arena;
126 a0d146ed 2005-07-12 devnull u64int offset, aoffset;
127 a0d146ed 2005-07-12 devnull Part *part;
128 a0d146ed 2005-07-12 devnull Dir *d;
129 a0d146ed 2005-07-12 devnull uchar buf[8192];
130 a0d146ed 2005-07-12 devnull ArenaHead head;
131 a0d146ed 2005-07-12 devnull ZClump zerocl;
132 a0d146ed 2005-07-12 devnull
133 a0d146ed 2005-07-12 devnull qlock(&godot);
134 a0d146ed 2005-07-12 devnull aoffset = 0;
135 a0d146ed 2005-07-12 devnull ARGBEGIN{
136 a0d146ed 2005-07-12 devnull case 'f':
137 a0d146ed 2005-07-12 devnull fast = 1;
138 a0d146ed 2005-07-12 devnull ventidoublechecksha1 = 0;
139 a0d146ed 2005-07-12 devnull break;
140 a0d146ed 2005-07-12 devnull case 'h':
141 a0d146ed 2005-07-12 devnull host = EARGF(usage());
142 a0d146ed 2005-07-12 devnull break;
143 a0d146ed 2005-07-12 devnull case 'o':
144 a0d146ed 2005-07-12 devnull haveaoffset = 1;
145 a0d146ed 2005-07-12 devnull aoffset = strtoull(EARGF(usage()), 0, 0);
146 a0d146ed 2005-07-12 devnull break;
147 a0d146ed 2005-07-12 devnull case 'M':
148 a0d146ed 2005-07-12 devnull maxwrites = atoi(EARGF(usage()));
149 a0d146ed 2005-07-12 devnull break;
150 a0d146ed 2005-07-12 devnull default:
151 a0d146ed 2005-07-12 devnull usage();
152 a0d146ed 2005-07-12 devnull break;
153 a0d146ed 2005-07-12 devnull }ARGEND
154 a0d146ed 2005-07-12 devnull
155 a0d146ed 2005-07-12 devnull offset = ~(u64int)0;
156 a0d146ed 2005-07-12 devnull switch(argc) {
157 a0d146ed 2005-07-12 devnull default:
158 a0d146ed 2005-07-12 devnull usage();
159 a0d146ed 2005-07-12 devnull case 2:
160 a0d146ed 2005-07-12 devnull offset = strtoull(argv[1], 0, 0);
161 a0d146ed 2005-07-12 devnull /* fall through */
162 a0d146ed 2005-07-12 devnull case 1:
163 a0d146ed 2005-07-12 devnull file = argv[0];
164 a0d146ed 2005-07-12 devnull }
165 a0d146ed 2005-07-12 devnull
166 a0d146ed 2005-07-12 devnull fmtinstall('V', vtscorefmt);
167 a0d146ed 2005-07-12 devnull
168 a0d146ed 2005-07-12 devnull statsinit();
169 a0d146ed 2005-07-12 devnull
170 a0d146ed 2005-07-12 devnull if((d = dirstat(file)) == nil)
171 a0d146ed 2005-07-12 devnull sysfatal("can't stat file %s: %r", file);
172 a0d146ed 2005-07-12 devnull
173 a0d146ed 2005-07-12 devnull part = initpart(file, OREAD);
174 a0d146ed 2005-07-12 devnull if(part == nil)
175 a0d146ed 2005-07-12 devnull sysfatal("can't open file %s: %r", file);
176 a0d146ed 2005-07-12 devnull if(readpart(part, aoffset, buf, sizeof buf) < 0)
177 a0d146ed 2005-07-12 devnull sysfatal("can't read file %s: %r", file);
178 a0d146ed 2005-07-12 devnull
179 a0d146ed 2005-07-12 devnull if(unpackarenahead(&head, buf) < 0)
180 a0d146ed 2005-07-12 devnull sysfatal("corrupted arena header: %r");
181 a0d146ed 2005-07-12 devnull
182 a0d146ed 2005-07-12 devnull if(aoffset+head.size > d->length)
183 a0d146ed 2005-07-12 devnull sysfatal("arena is truncated: want %llud bytes have %llud\n",
184 a0d146ed 2005-07-12 devnull head.size, d->length);
185 a0d146ed 2005-07-12 devnull
186 a0d146ed 2005-07-12 devnull partblocksize(part, head.blocksize);
187 a0d146ed 2005-07-12 devnull initdcache(8 * MaxDiskBlock);
188 a0d146ed 2005-07-12 devnull
189 a0d146ed 2005-07-12 devnull arena = initarena(part, aoffset, head.size, head.blocksize);
190 a0d146ed 2005-07-12 devnull if(arena == nil)
191 a0d146ed 2005-07-12 devnull sysfatal("initarena: %r");
192 a0d146ed 2005-07-12 devnull
193 23fb2edb 2005-07-24 devnull z = nil;
194 23fb2edb 2005-07-24 devnull if(host==nil || strcmp(host, "/dev/null") != 0){
195 a0d146ed 2005-07-12 devnull z = vtdial(host);
196 a0d146ed 2005-07-12 devnull if(z == nil)
197 a0d146ed 2005-07-12 devnull sysfatal("could not connect to server: %r");
198 a0d146ed 2005-07-12 devnull if(vtconnect(z) < 0)
199 a0d146ed 2005-07-12 devnull sysfatal("vtconnect: %r");
200 23fb2edb 2005-07-24 devnull }
201 a0d146ed 2005-07-12 devnull
202 a0d146ed 2005-07-12 devnull c = chancreate(sizeof(ZClump), 0);
203 a0d146ed 2005-07-12 devnull for(i=0; i<12; i++)
204 a0d146ed 2005-07-12 devnull vtproc(vtsendthread, nil);
205 a0d146ed 2005-07-12 devnull
206 a0d146ed 2005-07-12 devnull rdarena(arena, offset);
207 a0d146ed 2005-07-12 devnull if(vtsync(z) < 0)
208 a0d146ed 2005-07-12 devnull sysfatal("executing sync: %r");
209 a0d146ed 2005-07-12 devnull
210 a0d146ed 2005-07-12 devnull memset(&zerocl, 0, sizeof zerocl);
211 a0d146ed 2005-07-12 devnull for(i=0; i<12; i++)
212 a0d146ed 2005-07-12 devnull send(c, &zerocl);
213 a0d146ed 2005-07-12 devnull if(z){
214 a0d146ed 2005-07-12 devnull vthangup(z);
215 a0d146ed 2005-07-12 devnull }
216 a0d146ed 2005-07-12 devnull threadexitsall(0);
217 a0d146ed 2005-07-12 devnull }