Blame


1 43b99cd9 2007-04-21 devnull #include "stdinc.h"
2 43b99cd9 2007-04-21 devnull #include "dat.h"
3 43b99cd9 2007-04-21 devnull #include "fns.h"
4 43b99cd9 2007-04-21 devnull
5 43b99cd9 2007-04-21 devnull static uchar *data;
6 43b99cd9 2007-04-21 devnull static uchar *data1;
7 43b99cd9 2007-04-21 devnull static int blocksize;
8 43b99cd9 2007-04-21 devnull static int sleepms;
9 9f8a101a 2008-04-16 rsc static int fd;
10 9f8a101a 2008-04-16 rsc static int force;
11 9f8a101a 2008-04-16 rsc static vlong offset0;
12 43b99cd9 2007-04-21 devnull
13 43b99cd9 2007-04-21 devnull void
14 43b99cd9 2007-04-21 devnull usage(void)
15 43b99cd9 2007-04-21 devnull {
16 9f8a101a 2008-04-16 rsc fprint(2, "usage: reseal [-f] [-b blocksize] [-s ms] arenapart1 [name...]]\n");
17 43b99cd9 2007-04-21 devnull threadexitsall(0);
18 43b99cd9 2007-04-21 devnull }
19 43b99cd9 2007-04-21 devnull
20 43b99cd9 2007-04-21 devnull static int
21 9f8a101a 2008-04-16 rsc pwriteblock(uchar *buf, int n, vlong off)
22 43b99cd9 2007-04-21 devnull {
23 43b99cd9 2007-04-21 devnull int nr, m;
24 43b99cd9 2007-04-21 devnull
25 43b99cd9 2007-04-21 devnull for(nr = 0; nr < n; nr += m){
26 43b99cd9 2007-04-21 devnull m = n - nr;
27 9f8a101a 2008-04-16 rsc m = pwrite(fd, &buf[nr], m, offset0+off+nr);
28 43b99cd9 2007-04-21 devnull if(m <= 0)
29 43b99cd9 2007-04-21 devnull return -1;
30 43b99cd9 2007-04-21 devnull }
31 43b99cd9 2007-04-21 devnull return 0;
32 43b99cd9 2007-04-21 devnull }
33 43b99cd9 2007-04-21 devnull
34 43b99cd9 2007-04-21 devnull static int
35 9f8a101a 2008-04-16 rsc preadblock(uchar *buf, int n, vlong off)
36 43b99cd9 2007-04-21 devnull {
37 43b99cd9 2007-04-21 devnull int nr, m;
38 43b99cd9 2007-04-21 devnull
39 43b99cd9 2007-04-21 devnull for(nr = 0; nr < n; nr += m){
40 43b99cd9 2007-04-21 devnull m = n - nr;
41 9f8a101a 2008-04-16 rsc m = pread(fd, &buf[nr], m, offset0+off+nr);
42 43b99cd9 2007-04-21 devnull if(m <= 0){
43 43b99cd9 2007-04-21 devnull if(m == 0)
44 43b99cd9 2007-04-21 devnull werrstr("early eof");
45 43b99cd9 2007-04-21 devnull return -1;
46 43b99cd9 2007-04-21 devnull }
47 43b99cd9 2007-04-21 devnull }
48 43b99cd9 2007-04-21 devnull return 0;
49 43b99cd9 2007-04-21 devnull }
50 43b99cd9 2007-04-21 devnull
51 43b99cd9 2007-04-21 devnull static int
52 9f8a101a 2008-04-16 rsc loadheader(char *name, ArenaHead *head, Arena *arena, vlong off)
53 43b99cd9 2007-04-21 devnull {
54 9f8a101a 2008-04-16 rsc if(preadblock(data, head->blocksize, off + head->size - head->blocksize) < 0){
55 43b99cd9 2007-04-21 devnull fprint(2, "%s: reading arena tail: %r\n", name);
56 43b99cd9 2007-04-21 devnull return -1;
57 43b99cd9 2007-04-21 devnull }
58 43b99cd9 2007-04-21 devnull
59 43b99cd9 2007-04-21 devnull memset(arena, 0, sizeof *arena);
60 43b99cd9 2007-04-21 devnull if(unpackarena(arena, data) < 0){
61 43b99cd9 2007-04-21 devnull fprint(2, "%s: unpack arena tail: %r\n", name);
62 43b99cd9 2007-04-21 devnull return -1;
63 43b99cd9 2007-04-21 devnull }
64 43b99cd9 2007-04-21 devnull arena->blocksize = head->blocksize;
65 43b99cd9 2007-04-21 devnull arena->base = off + head->blocksize;
66 43b99cd9 2007-04-21 devnull arena->clumpmax = arena->blocksize / ClumpInfoSize;
67 43b99cd9 2007-04-21 devnull arena->size = head->size - 2*head->blocksize;
68 43b99cd9 2007-04-21 devnull
69 43b99cd9 2007-04-21 devnull if(arena->diskstats.sealed)
70 43b99cd9 2007-04-21 devnull scorecp(arena->score, data + head->blocksize - VtScoreSize);
71 43b99cd9 2007-04-21 devnull return 0;
72 43b99cd9 2007-04-21 devnull }
73 43b99cd9 2007-04-21 devnull
74 43b99cd9 2007-04-21 devnull uchar zero[VtScoreSize];
75 43b99cd9 2007-04-21 devnull
76 43b99cd9 2007-04-21 devnull static int
77 9f8a101a 2008-04-16 rsc verify(Arena *arena, void *data, uchar *newscore)
78 43b99cd9 2007-04-21 devnull {
79 43b99cd9 2007-04-21 devnull vlong e, bs, n, o;
80 43b99cd9 2007-04-21 devnull DigestState ds, ds1;
81 43b99cd9 2007-04-21 devnull uchar score[VtScoreSize];
82 43b99cd9 2007-04-21 devnull
83 43b99cd9 2007-04-21 devnull /*
84 43b99cd9 2007-04-21 devnull * now we know how much to read
85 43b99cd9 2007-04-21 devnull * read everything but the last block, which is special
86 43b99cd9 2007-04-21 devnull */
87 43b99cd9 2007-04-21 devnull e = arena->size + arena->blocksize;
88 43b99cd9 2007-04-21 devnull o = arena->base - arena->blocksize;
89 43b99cd9 2007-04-21 devnull bs = arena->blocksize;
90 43b99cd9 2007-04-21 devnull memset(&ds, 0, sizeof ds);
91 43b99cd9 2007-04-21 devnull for(n = 0; n < e; n += bs){
92 9f8a101a 2008-04-16 rsc if(preadblock(data, bs, o + n) < 0){
93 43b99cd9 2007-04-21 devnull werrstr("read: %r");
94 43b99cd9 2007-04-21 devnull return -1;
95 43b99cd9 2007-04-21 devnull }
96 43b99cd9 2007-04-21 devnull if(n + bs > e)
97 43b99cd9 2007-04-21 devnull bs = e - n;
98 43b99cd9 2007-04-21 devnull sha1(data, bs, nil, &ds);
99 43b99cd9 2007-04-21 devnull }
100 fa325e9b 2020-01-10 cross
101 43b99cd9 2007-04-21 devnull /* last block */
102 9f8a101a 2008-04-16 rsc if(preadblock(data, arena->blocksize, o + e) < 0){
103 43b99cd9 2007-04-21 devnull werrstr("read: %r");
104 43b99cd9 2007-04-21 devnull return -1;
105 43b99cd9 2007-04-21 devnull }
106 43b99cd9 2007-04-21 devnull ds1 = ds;
107 43b99cd9 2007-04-21 devnull sha1(data, bs - VtScoreSize, nil, &ds);
108 43b99cd9 2007-04-21 devnull sha1(zero, VtScoreSize, score, &ds);
109 43b99cd9 2007-04-21 devnull if(scorecmp(score, arena->score) != 0){
110 9f8a101a 2008-04-16 rsc if(!force){
111 9f8a101a 2008-04-16 rsc werrstr("score mismatch: %V != %V", score, arena->score);
112 9f8a101a 2008-04-16 rsc return -1;
113 9f8a101a 2008-04-16 rsc }
114 9f8a101a 2008-04-16 rsc fprint(2, "warning: score mismatch %V != %V\n", score, arena->score);
115 43b99cd9 2007-04-21 devnull }
116 fa325e9b 2020-01-10 cross
117 43b99cd9 2007-04-21 devnull /* prepare new last block */
118 43b99cd9 2007-04-21 devnull memset(data, 0, arena->blocksize);
119 43b99cd9 2007-04-21 devnull packarena(arena, data);
120 43b99cd9 2007-04-21 devnull sha1(data, bs, newscore, &ds1);
121 43b99cd9 2007-04-21 devnull scorecp((uchar*)data + arena->blocksize - VtScoreSize, newscore);
122 43b99cd9 2007-04-21 devnull
123 43b99cd9 2007-04-21 devnull return 0;
124 43b99cd9 2007-04-21 devnull }
125 43b99cd9 2007-04-21 devnull
126 43b99cd9 2007-04-21 devnull static void
127 43b99cd9 2007-04-21 devnull resealarena(char *name, vlong len)
128 43b99cd9 2007-04-21 devnull {
129 43b99cd9 2007-04-21 devnull ArenaHead head;
130 43b99cd9 2007-04-21 devnull Arena arena;
131 43b99cd9 2007-04-21 devnull DigestState s;
132 43b99cd9 2007-04-21 devnull u64int off;
133 43b99cd9 2007-04-21 devnull uchar newscore[VtScoreSize];
134 43b99cd9 2007-04-21 devnull
135 43b99cd9 2007-04-21 devnull fprint(2, "%s: begin reseal\n", name);
136 43b99cd9 2007-04-21 devnull
137 43b99cd9 2007-04-21 devnull memset(&s, 0, sizeof s);
138 43b99cd9 2007-04-21 devnull
139 43b99cd9 2007-04-21 devnull off = seek(fd, 0, 1);
140 43b99cd9 2007-04-21 devnull
141 43b99cd9 2007-04-21 devnull /*
142 43b99cd9 2007-04-21 devnull * read a little bit, which will include the header
143 43b99cd9 2007-04-21 devnull */
144 9f8a101a 2008-04-16 rsc if(preadblock(data, HeadSize, off) < 0){
145 43b99cd9 2007-04-21 devnull fprint(2, "%s: reading header: %r\n", name);
146 43b99cd9 2007-04-21 devnull return;
147 43b99cd9 2007-04-21 devnull }
148 43b99cd9 2007-04-21 devnull if(unpackarenahead(&head, data) < 0){
149 43b99cd9 2007-04-21 devnull fprint(2, "%s: corrupt arena header: %r\n", name);
150 43b99cd9 2007-04-21 devnull return;
151 43b99cd9 2007-04-21 devnull }
152 43b99cd9 2007-04-21 devnull if(head.version != ArenaVersion4 && head.version != ArenaVersion5)
153 43b99cd9 2007-04-21 devnull fprint(2, "%s: warning: unknown arena version %d\n", name, head.version);
154 43b99cd9 2007-04-21 devnull if(len != 0 && len != head.size)
155 43b99cd9 2007-04-21 devnull fprint(2, "%s: warning: unexpected length %lld != %lld\n", name, head.size, len);
156 43b99cd9 2007-04-21 devnull if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
157 43b99cd9 2007-04-21 devnull fprint(2, "%s: warning: unexpected name %s\n", name, head.name);
158 43b99cd9 2007-04-21 devnull
159 9f8a101a 2008-04-16 rsc if(loadheader(name, &head, &arena, off) < 0)
160 43b99cd9 2007-04-21 devnull return;
161 fa325e9b 2020-01-10 cross
162 43b99cd9 2007-04-21 devnull if(!arena.diskstats.sealed){
163 43b99cd9 2007-04-21 devnull fprint(2, "%s: not sealed\n", name);
164 43b99cd9 2007-04-21 devnull return;
165 43b99cd9 2007-04-21 devnull }
166 fa325e9b 2020-01-10 cross
167 9f8a101a 2008-04-16 rsc if(verify(&arena, data, newscore) < 0){
168 43b99cd9 2007-04-21 devnull fprint(2, "%s: failed to verify before reseal: %r\n", name);
169 43b99cd9 2007-04-21 devnull return;
170 43b99cd9 2007-04-21 devnull }
171 fa325e9b 2020-01-10 cross
172 9f8a101a 2008-04-16 rsc if(pwriteblock(data, arena.blocksize, arena.base + arena.size) < 0){
173 43b99cd9 2007-04-21 devnull fprint(2, "%s: writing new tail: %r\n", name);
174 43b99cd9 2007-04-21 devnull return;
175 43b99cd9 2007-04-21 devnull }
176 43b99cd9 2007-04-21 devnull scorecp(arena.score, newscore);
177 43b99cd9 2007-04-21 devnull fprint(2, "%s: resealed: %V\n", name, newscore);
178 43b99cd9 2007-04-21 devnull
179 9f8a101a 2008-04-16 rsc if(verify(&arena, data, newscore) < 0){
180 43b99cd9 2007-04-21 devnull fprint(2, "%s: failed to verify after reseal!: %r\n", name);
181 43b99cd9 2007-04-21 devnull return;
182 43b99cd9 2007-04-21 devnull }
183 43b99cd9 2007-04-21 devnull
184 43b99cd9 2007-04-21 devnull fprint(2, "%s: verified: %V\n", name, newscore);
185 43b99cd9 2007-04-21 devnull }
186 43b99cd9 2007-04-21 devnull
187 43b99cd9 2007-04-21 devnull static int
188 43b99cd9 2007-04-21 devnull shouldcheck(char *name, char **s, int n)
189 43b99cd9 2007-04-21 devnull {
190 43b99cd9 2007-04-21 devnull int i;
191 fa325e9b 2020-01-10 cross
192 43b99cd9 2007-04-21 devnull if(n == 0)
193 43b99cd9 2007-04-21 devnull return 1;
194 43b99cd9 2007-04-21 devnull
195 43b99cd9 2007-04-21 devnull for(i=0; i<n; i++){
196 43b99cd9 2007-04-21 devnull if(s[i] && strcmp(name, s[i]) == 0){
197 43b99cd9 2007-04-21 devnull s[i] = nil;
198 43b99cd9 2007-04-21 devnull return 1;
199 43b99cd9 2007-04-21 devnull }
200 43b99cd9 2007-04-21 devnull }
201 43b99cd9 2007-04-21 devnull return 0;
202 43b99cd9 2007-04-21 devnull }
203 43b99cd9 2007-04-21 devnull
204 43b99cd9 2007-04-21 devnull char *
205 9f8a101a 2008-04-16 rsc readap(ArenaPart *ap)
206 43b99cd9 2007-04-21 devnull {
207 43b99cd9 2007-04-21 devnull char *table;
208 fa325e9b 2020-01-10 cross
209 9f8a101a 2008-04-16 rsc if(preadblock(data, 8192, PartBlank) < 0)
210 43b99cd9 2007-04-21 devnull sysfatal("read arena part header: %r");
211 43b99cd9 2007-04-21 devnull if(unpackarenapart(ap, data) < 0)
212 43b99cd9 2007-04-21 devnull sysfatal("corrupted arena part header: %r");
213 43b99cd9 2007-04-21 devnull fprint(2, "# arena part version=%d blocksize=%d arenabase=%d\n",
214 43b99cd9 2007-04-21 devnull ap->version, ap->blocksize, ap->arenabase);
215 43b99cd9 2007-04-21 devnull ap->tabbase = (PartBlank+HeadSize+ap->blocksize-1)&~(ap->blocksize-1);
216 43b99cd9 2007-04-21 devnull ap->tabsize = ap->arenabase - ap->tabbase;
217 43b99cd9 2007-04-21 devnull table = malloc(ap->tabsize+1);
218 9f8a101a 2008-04-16 rsc if(preadblock((uchar*)table, ap->tabsize, ap->tabbase) < 0)
219 43b99cd9 2007-04-21 devnull sysfatal("reading arena part directory: %r");
220 43b99cd9 2007-04-21 devnull table[ap->tabsize] = 0;
221 43b99cd9 2007-04-21 devnull return table;
222 43b99cd9 2007-04-21 devnull }
223 43b99cd9 2007-04-21 devnull
224 43b99cd9 2007-04-21 devnull void
225 43b99cd9 2007-04-21 devnull threadmain(int argc, char *argv[])
226 43b99cd9 2007-04-21 devnull {
227 43b99cd9 2007-04-21 devnull int i, nline;
228 43b99cd9 2007-04-21 devnull char *p, *q, *table, *f[10], line[256];
229 43b99cd9 2007-04-21 devnull vlong start, stop;
230 43b99cd9 2007-04-21 devnull ArenaPart ap;
231 9f8a101a 2008-04-16 rsc Part *part;
232 fa325e9b 2020-01-10 cross
233 43b99cd9 2007-04-21 devnull ventifmtinstall();
234 43b99cd9 2007-04-21 devnull blocksize = MaxIoSize;
235 43b99cd9 2007-04-21 devnull ARGBEGIN{
236 43b99cd9 2007-04-21 devnull case 'b':
237 43b99cd9 2007-04-21 devnull blocksize = unittoull(EARGF(usage()));
238 43b99cd9 2007-04-21 devnull break;
239 9f8a101a 2008-04-16 rsc case 'f':
240 9f8a101a 2008-04-16 rsc force = 1;
241 9f8a101a 2008-04-16 rsc break;
242 43b99cd9 2007-04-21 devnull case 's':
243 43b99cd9 2007-04-21 devnull sleepms = atoi(EARGF(usage()));
244 43b99cd9 2007-04-21 devnull break;
245 43b99cd9 2007-04-21 devnull default:
246 43b99cd9 2007-04-21 devnull usage();
247 43b99cd9 2007-04-21 devnull break;
248 43b99cd9 2007-04-21 devnull }ARGEND
249 43b99cd9 2007-04-21 devnull
250 43b99cd9 2007-04-21 devnull if(argc < 2)
251 43b99cd9 2007-04-21 devnull usage();
252 43b99cd9 2007-04-21 devnull
253 43b99cd9 2007-04-21 devnull data = vtmalloc(blocksize);
254 9f8a101a 2008-04-16 rsc if((part = initpart(argv[0], ORDWR)) == nil)
255 9f8a101a 2008-04-16 rsc sysfatal("open partition %s: %r", argv[0]);
256 9f8a101a 2008-04-16 rsc fd = part->fd;
257 9f8a101a 2008-04-16 rsc offset0 = part->offset;
258 43b99cd9 2007-04-21 devnull
259 9f8a101a 2008-04-16 rsc table = readap(&ap);
260 43b99cd9 2007-04-21 devnull
261 43b99cd9 2007-04-21 devnull nline = atoi(table);
262 43b99cd9 2007-04-21 devnull p = strchr(table, '\n');
263 43b99cd9 2007-04-21 devnull if(p)
264 43b99cd9 2007-04-21 devnull p++;
265 43b99cd9 2007-04-21 devnull for(i=0; i<nline; i++){
266 43b99cd9 2007-04-21 devnull if(p == nil){
267 43b99cd9 2007-04-21 devnull fprint(2, "warning: unexpected arena table end\n");
268 43b99cd9 2007-04-21 devnull break;
269 43b99cd9 2007-04-21 devnull }
270 43b99cd9 2007-04-21 devnull q = strchr(p, '\n');
271 43b99cd9 2007-04-21 devnull if(q)
272 43b99cd9 2007-04-21 devnull *q++ = 0;
273 43b99cd9 2007-04-21 devnull if(strlen(p) >= sizeof line){
274 43b99cd9 2007-04-21 devnull fprint(2, "warning: long arena table line: %s\n", p);
275 43b99cd9 2007-04-21 devnull p = q;
276 43b99cd9 2007-04-21 devnull continue;
277 43b99cd9 2007-04-21 devnull }
278 43b99cd9 2007-04-21 devnull strcpy(line, p);
279 43b99cd9 2007-04-21 devnull memset(f, 0, sizeof f);
280 43b99cd9 2007-04-21 devnull if(tokenize(line, f, nelem(f)) < 3){
281 43b99cd9 2007-04-21 devnull fprint(2, "warning: bad arena table line: %s\n", p);
282 43b99cd9 2007-04-21 devnull p = q;
283 43b99cd9 2007-04-21 devnull continue;
284 43b99cd9 2007-04-21 devnull }
285 43b99cd9 2007-04-21 devnull p = q;
286 43b99cd9 2007-04-21 devnull if(shouldcheck(f[0], argv+1, argc-1)){
287 43b99cd9 2007-04-21 devnull start = strtoull(f[1], 0, 0);
288 43b99cd9 2007-04-21 devnull stop = strtoull(f[2], 0, 0);
289 43b99cd9 2007-04-21 devnull if(stop <= start){
290 43b99cd9 2007-04-21 devnull fprint(2, "%s: bad start,stop %lld,%lld\n", f[0], stop, start);
291 43b99cd9 2007-04-21 devnull continue;
292 43b99cd9 2007-04-21 devnull }
293 43b99cd9 2007-04-21 devnull if(seek(fd, start, 0) < 0)
294 43b99cd9 2007-04-21 devnull fprint(2, "%s: seek to start: %r\n", f[0]);
295 43b99cd9 2007-04-21 devnull resealarena(f[0], stop - start);
296 43b99cd9 2007-04-21 devnull }
297 43b99cd9 2007-04-21 devnull }
298 43b99cd9 2007-04-21 devnull for(i=2; i<argc; i++)
299 43b99cd9 2007-04-21 devnull if(argv[i] != 0)
300 43b99cd9 2007-04-21 devnull fprint(2, "%s: did not find arena\n", argv[i]);
301 43b99cd9 2007-04-21 devnull
302 43b99cd9 2007-04-21 devnull threadexitsall(nil);
303 43b99cd9 2007-04-21 devnull }