Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/venti/srv/verifyarena.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "stdinc.h"
2
#include "dat.h"
3
#include "fns.h"
4
 
5
static int	verbose;
6
static int	fd;
7
static uchar	*data;
8
static int	blocksize;
9
static int	sleepms;
10
static vlong offset0;
11
 
12
void
13
usage(void)
14
{
15
	fprint(2, "usage: verifyarena [-b blocksize] [-s ms] [-v] [arenapart [name...]]\n");
16
	threadexitsall(0);
17
}
18
 
19
static int
20
preadblock(uchar *buf, int n, vlong off)
21
{
22
	int nr, m;
23
 
24
	for(nr = 0; nr < n; nr += m){
25
		m = n - nr;
26
		m = pread(fd, &buf[nr], m, offset0+off+nr);
27
		if(m <= 0){
28
			if(m == 0)
29
				werrstr("early eof");
30
			return -1;
31
		}
32
	}
33
	return 0;
34
}
35
 
36
static int
37
readblock(uchar *buf, int n)
38
{
39
	int nr, m;
40
 
41
	for(nr = 0; nr < n; nr += m){
42
		m = n - nr;
43
		m = read(fd, &buf[nr], m);
44
		if(m <= 0){
45
			if(m == 0)
46
				werrstr("early eof");
47
			return -1;
48
		}
49
	}
50
	return 0;
51
}
52
 
53
static void
54
verifyarena(char *name, vlong len)
55
{
56
	Arena arena;
57
	ArenaHead head;
58
	DigestState s;
59
	u64int n, e;
60
	u32int bs;
61
	u8int score[VtScoreSize];
62
 
63
	fprint(2, "%T verify %s\n", name);
64
 
65
	memset(&arena, 0, sizeof arena);
66
	memset(&s, 0, sizeof s);
67
 
68
	/*
69
	 * read a little bit, which will include the header
70
	 */
71
	if(readblock(data, HeadSize) < 0){
72
		fprint(2, "%T %s: reading header: %r\n", name);
73
		return;
74
	}
75
	sha1(data, HeadSize, nil, &s);
76
	if(unpackarenahead(&head, data) < 0){
77
		fprint(2, "%T %s: corrupt arena header: %r\n", name);
78
		return;
79
	}
80
	if(head.version != ArenaVersion4 && head.version != ArenaVersion5)
81
		fprint(2, "%T %s: warning: unknown arena version %d\n", name, head.version);
82
	if(len != 0 && len != head.size)
83
		fprint(2, "%T %s: warning: unexpected length %lld != %lld\n", name, head.size, len);
84
	if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
85
		fprint(2, "%T %s: warning: unexpected name %s\n", name, head.name);
86
 
87
	/*
88
	 * now we know how much to read
89
	 * read everything but the last block, which is special
90
	 */
91
	e = head.size - head.blocksize;
92
	bs = blocksize;
93
	for(n = HeadSize; n < e; n += bs){
94
		if(n + bs > e)
95
			bs = e - n;
96
		if(readblock(data, bs) < 0){
97
			fprint(2, "%T %s: read data: %r\n", name);
98
			return;
99
		}
100
		sha1(data, bs, nil, &s);
101
		if(sleepms)
102
			sleep(sleepms);
103
	}
104
 
105
	/*
106
	 * read the last block update the sum.
107
	 * the sum is calculated assuming the slot for the sum is zero.
108
	 */
109
	bs = head.blocksize;
110
	if(readblock(data, bs) < 0){
111
		fprint(2, "%T %s: read last block: %r\n", name);
112
		return;
113
	}
114
	sha1(data, bs-VtScoreSize, nil, &s);
115
	sha1(zeroscore, VtScoreSize, nil, &s);
116
	sha1(nil, 0, score, &s);
117
 
118
	/*
119
	 * validity check on the trailer
120
	 */
121
	arena.blocksize = head.blocksize;
122
	if(unpackarena(&arena, data) < 0){
123
		fprint(2, "%T %s: corrupt arena trailer: %r\n", name);
124
		return;
125
	}
126
	scorecp(arena.score, &data[arena.blocksize - VtScoreSize]);
127
 
128
	if(namecmp(arena.name, head.name) != 0){
129
		fprint(2, "%T %s: wrong name in trailer: %s vs. %s\n", 
130
			name, head.name, arena.name);
131
		return;
132
	}
133
	if(arena.version != head.version){
134
		fprint(2, "%T %s: wrong version in trailer: %d vs. %d\n", 
135
			name, head.version, arena.version);
136
		return;
137
	}
138
	arena.size = head.size - 2 * head.blocksize;
139
 
140
	/*
141
	 * check for no checksum or the same
142
	 */
143
	if(scorecmp(score, arena.score) == 0)
144
		fprint(2, "%T %s: verified score\n", name);
145
	else if(scorecmp(zeroscore, arena.score) == 0)
146
		fprint(2, "%T %s: unsealed\n", name);
147
	else{
148
		fprint(2, "%T %s: mismatch checksum - found=%V calculated=%V\n",
149
			name, arena.score, score);
150
		return;
151
	}
152
	printarena(2, &arena);
153
}
154
 
155
static int
156
shouldcheck(char *name, char **s, int n)
157
{
158
	int i;
159
 
160
	if(n == 0)
161
		return 1;
162
 
163
	for(i=0; i<n; i++){
164
		if(s[i] && strcmp(name, s[i]) == 0){
165
			s[i] = nil;
166
			return 1;
167
		}
168
	}
169
	return 0;
170
}
171
 
172
void
173
threadmain(int argc, char *argv[])
174
{
175
	int i, nline;
176
	char *p, *q, *table, *f[10], line[256];
177
	vlong start, stop;
178
	ArenaPart ap;
179
	Part *part;
180
 
181
	needzeroscore();
182
	ventifmtinstall();
183
	blocksize = MaxIoSize;
184
	ARGBEGIN{
185
	case 'b':
186
		blocksize = unittoull(EARGF(usage()));
187
		break;
188
	case 's':
189
		sleepms = atoi(EARGF(usage()));
190
		break;
191
	case 'v':
192
		verbose++;
193
		break;
194
	default:
195
		usage();
196
		break;
197
	}ARGEND
198
 
199
	data = vtmalloc(blocksize);
200
	if(argc == 0){
201
		fd = 0;
202
		verifyarena("<stdin>", 0);
203
		threadexitsall(nil);
204
	}
205
 
206
	if((part = initpart(argv[0], OREAD)) == nil)
207
		sysfatal("open partition %s: %r", argv[0]);
208
	fd = part->fd;
209
	offset0 = part->offset;
210
 
211
	if(preadblock(data, 8192, PartBlank) < 0)
212
		sysfatal("read arena part header: %r");
213
	if(unpackarenapart(&ap, data) < 0)
214
		sysfatal("corrupted arena part header: %r");
215
	fprint(2, "%T # arena part version=%d blocksize=%d arenabase=%d\n",
216
		ap.version, ap.blocksize, ap.arenabase);
217
	ap.tabbase = (PartBlank+HeadSize+ap.blocksize-1)&~(ap.blocksize-1);
218
	ap.tabsize = ap.arenabase - ap.tabbase;
219
	table = malloc(ap.tabsize+1);
220
	if(preadblock((uchar*)table, ap.tabsize, ap.tabbase) < 0)
221
		sysfatal("reading arena part directory: %r");
222
	table[ap.tabsize] = 0;
223
 
224
	nline = atoi(table);
225
	p = strchr(table, '\n');
226
	if(p)
227
		p++;
228
	for(i=0; i<nline; i++){
229
		if(p == nil){
230
			fprint(2, "%T warning: unexpected arena table end\n");
231
			break;
232
		}
233
		q = strchr(p, '\n');
234
		if(q)
235
			*q++ = 0;
236
		if(strlen(p) >= sizeof line){
237
			fprint(2, "%T warning: long arena table line: %s\n", p);
238
			p = q;
239
			continue;
240
		}
241
		strcpy(line, p);
242
		memset(f, 0, sizeof f);
243
		if(tokenize(line, f, nelem(f)) < 3){
244
			fprint(2, "%T warning: bad arena table line: %s\n", p);
245
			p = q;
246
			continue;
247
		}
248
		p = q;
249
		if(shouldcheck(f[0], argv+1, argc-1)){
250
			start = strtoull(f[1], 0, 0);
251
			stop = strtoull(f[2], 0, 0);
252
			if(stop <= start){
253
				fprint(2, "%T %s: bad start,stop %lld,%lld\n", f[0], stop, start);
254
				continue;
255
			}
256
			if(seek(fd, offset0+start, 0) < 0)
257
				fprint(2, "%T %s: seek to start: %r\n", f[0]);
258
			verifyarena(f[0], stop - start);
259
		}
260
	}
261
	for(i=1; i<argc; i++)
262
		if(argv[i] != 0)
263
			fprint(2, "%T %s: did not find arena\n", argv[i]);
264
 
265
	threadexitsall(nil);
266
}