Beispiel #1
0
/*
 * read the arena header and trailer blocks from disk
 */
static int
loadarena(Arena *arena)
{
	ArenaHead head;
	ZBlock *b;

	b = alloczblock(arena->blocksize, 0, arena->part->blocksize);
	if(b == nil)
		return -1;
	if(readpart(arena->part, arena->base + arena->size, b->data, arena->blocksize) < 0){
		freezblock(b);
		return -1;
	}
	if(unpackarena(arena, b->data) < 0){
		freezblock(b);
		return -1;
	}
	if(arena->version != ArenaVersion4 && arena->version != ArenaVersion5){
		seterr(EAdmin, "unknown arena version %d", arena->version);
		freezblock(b);
		return -1;
	}
	scorecp(arena->score, &b->data[arena->blocksize - VtScoreSize]);

	if(readpart(arena->part, arena->base - arena->blocksize, b->data, arena->blocksize) < 0){
		logerr(EAdmin, "can't read arena header: %r");
		freezblock(b);
		return 0;
	}
	if(unpackarenahead(&head, b->data) < 0)
		logerr(ECorrupt, "corrupted arena header: %r");
	else if(namecmp(arena->name, head.name)!=0
	     || arena->clumpmagic != head.clumpmagic
	     || arena->version != head.version
	     || arena->blocksize != head.blocksize
	     || arena->size + 2 * arena->blocksize != head.size){
		if(namecmp(arena->name, head.name)!=0)
			logerr(ECorrupt, "arena tail name %s head %s", 
				arena->name, head.name);
		else if(arena->clumpmagic != head.clumpmagic)
			logerr(ECorrupt, "arena %d tail clumpmagic 0x%lux head 0x%lux",
				debugarena, (uint32_t)arena->clumpmagic,
				(uint32_t)head.clumpmagic);
		else if(arena->version != head.version)
			logerr(ECorrupt, "arena tail version %d head version %d",
				arena->version, head.version);
		else if(arena->blocksize != head.blocksize)
			logerr(ECorrupt, "arena tail block size %d head %d",
				arena->blocksize, head.blocksize);
		else if(arena->size+2*arena->blocksize != head.size)
			logerr(ECorrupt, "arena tail size %lud head %lud",
				(uint32_t)arena->size+2*arena->blocksize,
			       head.size);
		else
			logerr(ECorrupt, "arena header inconsistent with arena data");
	}
	freezblock(b);

	return 0;
}
Beispiel #2
0
static int
diskarenapart(HConnect *c, char *disk, Part *p)
{
	char *arenaname;
	ArenaPart ap;
	ArenaHead head;
	Arena arena;
	char *table;
	char *score;
	char *clump;
	uchar *blk;
	vlong start, end, off;
	char tbuf[60];

	hprint(&c->hout, "<h1>arena partition %s</h1>\n", disk);

	if((table = readap(p, &ap)) == nil){
		hprint(&c->hout, "%r\n");
		goto out;
	}
	
	hprint(&c->hout, "<pre>\n");
	hprint(&c->hout, "version=%d blocksize=%d base=%d\n",
		ap.version, ap.blocksize, ap.arenabase);
	hprint(&c->hout, "</pre>\n");

	arenaname = hargstr(c, "arena", "");
	if(arenaname[0] == 0){
		diskarenatable(c, disk, table);
		goto out;
	}
	
	if(xfindarena(table, arenaname, &start, &end) < 0){
		hprint(&c->hout, "no such arena %s\n", arenaname);
		goto out;
	}
	
	hprint(&c->hout, "<h2>arena %s</h2>\n", arenaname);
	hprint(&c->hout, "<pre>start=%#llx end=%#llx<pre>\n", start, end);
	if(end < start || end - start < HeadSize){
		hprint(&c->hout, "bad size %#llx\n", end - start);
		goto out;
	}

	// read arena header, tail
	blk = vtmalloc(HeadSize);
	if(readpart(p, start, blk, HeadSize) != HeadSize){
		hprint(&c->hout, "reading header: %r\n");
		vtfree(blk);
		goto out;
	}
	if(unpackarenahead(&head, blk) < 0){
		hprint(&c->hout, "corrupt arena header: %r\n");
		// hhex(blk, HeadSize);
		vtfree(blk);
		goto out;
	}
	vtfree(blk);

	hprint(&c->hout, "head:\n<pre>\n");
	hprint(&c->hout, "version=%d name=%s blocksize=%d size=%#llx clumpmagic=%#ux\n",
		head.version, head.name, head.blocksize, head.size, 
		head.clumpmagic);
	hprint(&c->hout, "</pre><br><br>\n");

	if(head.blocksize > MaxIoSize || head.blocksize >= end - start){
		hprint(&c->hout, "corrupt block size %d\n", head.blocksize);
		goto out;
	}

	blk = vtmalloc(head.blocksize);
	if(readpart(p, end - head.blocksize, blk, head.blocksize) < 0){
		hprint(&c->hout, "reading tail: %r\n");
		vtfree(blk);
		goto out;
	}
	memset(&arena, 0, sizeof arena);
	arena.part = p;
	arena.blocksize = head.blocksize;
	arena.clumpmax = head.blocksize / ClumpInfoSize;
	arena.base = start + head.blocksize;
	arena.size = end - start - 2 * head.blocksize;
	if(unpackarena(&arena, blk) < 0){
		vtfree(blk);
		goto out;
	}
	scorecp(arena.score, blk+head.blocksize - VtScoreSize);

	vtfree(blk);
	
	hprint(&c->hout, "tail:\n<pre>\n");
	hprint(&c->hout, "version=%d name=%s\n", arena.version, arena.name);
	hprint(&c->hout, "ctime=%d %s\n", arena.ctime, fmttime(tbuf, arena.ctime));
	hprint(&c->hout, "wtime=%d %s\n", arena.wtime, fmttime(tbuf, arena.wtime));
	hprint(&c->hout, "clumpmagic=%#ux\n", arena.clumpmagic);
	hprint(&c->hout, "score %V\n", arena.score);
	hprint(&c->hout, "diskstats:\n");
	hprint(&c->hout, "\tclumps=%,d cclumps=%,d used=%,lld uncsize=%,lld sealed=%d\n",
		arena.diskstats.clumps, arena.diskstats.cclumps,
		arena.diskstats.used, arena.diskstats.uncsize,
		arena.diskstats.sealed);
	hprint(&c->hout, "memstats:\n");
	hprint(&c->hout, "\tclumps=%,d cclumps=%,d used=%,lld uncsize=%,lld sealed=%d\n",
		arena.memstats.clumps, arena.memstats.cclumps,
		arena.memstats.used, arena.memstats.uncsize,
		arena.memstats.sealed);
	if(arena.clumpmax == 0){
		hprint(&c->hout, "bad clumpmax\n");
		goto out;
	}

	score = hargstr(c, "score", "");
	clump = hargstr(c, "clump", "");

	if(clump[0]){
		off = strtoull(clump, 0, 0);
		diskarenaclump(c, &arena, off, score[0] ? score : nil);
	}else if(score[0]){
		diskarenaclump(c, &arena, -1, score);
	}else{
		diskarenatoc(c, &arena);
	}

out:
	free(table);
	return 0;
}
Beispiel #3
0
void
threadmain(int argc, char *argv[])
{
	int i;
	char *file;
	Arena *arena;
	u64int offset, aoffset;
	Part *part;
	uchar buf[8192];
	ArenaHead head;
	ZClump zerocl;

	ventifmtinstall();
	qlock(&godot);
	aoffset = 0;
	ARGBEGIN{
	case 'f':
		fast = 1;
		ventidoublechecksha1 = 0;
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'o':
		haveaoffset = 1;
		aoffset = strtoull(EARGF(usage()), 0, 0);
		break;
	case 'M':
		maxwrites = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	default:
		usage();
		break;
	}ARGEND

	offset = ~(u64int)0;
	switch(argc) {
	default:
		usage();
	case 2:
		offset = strtoull(argv[1], 0, 0);
		/* fall through */
	case 1:
		file = argv[0];
	}

	fmtinstall('V', vtscorefmt);

	statsinit();

	part = initpart(file, OREAD);
	if(part == nil)
		sysfatal("can't open file %s: %r", file);
	if(readpart(part, aoffset, buf, sizeof buf) < 0)
		sysfatal("can't read file %s: %r", file);

	if(unpackarenahead(&head, buf) < 0)
		sysfatal("corrupted arena header: %r");

	if(aoffset+head.size > part->size)
		sysfatal("arena is truncated: want %llud bytes have %llud",
			head.size, part->size);

	partblocksize(part, head.blocksize);
	initdcache(8 * MaxDiskBlock);

	arena = initarena(part, aoffset, head.size, head.blocksize);
	if(arena == nil)
		sysfatal("initarena: %r");

	z = nil;
	if(host==nil || strcmp(host, "/dev/null") != 0){
		z = vtdial(host);
		if(z == nil)
			sysfatal("could not connect to server: %r");
		if(vtconnect(z) < 0)
			sysfatal("vtconnect: %r");
	}
	
	c = chancreate(sizeof(ZClump), 0);
	for(i=0; i<12; i++)
		vtproc(vtsendthread, nil);

	rdarena(arena, offset);
	if(vtsync(z) < 0)
		sysfatal("executing sync: %r");

	memset(&zerocl, 0, sizeof zerocl);
	for(i=0; i<12; i++)
		send(c, &zerocl);
	if(z){
		vthangup(z);
	}
	threadexitsall(0);
}
Beispiel #4
0
static void
cmparena(char *name, vlong len)
{
	ArenaHead head;
	DigestState s;
	u64int n, e;
	u32int bs;
	int i, j;
	char buf[20];

	fprint(2, "cmp %s\n", name);

	memset(&s, 0, sizeof s);

	/*
	 * read a little bit, which will include the header
	 */
	if(readblock(fd, data, HeadSize) < 0){
		fprint(2, "%s: reading header: %r\n", name);
		return;
	}
	if(unpackarenahead(&head, data) < 0){
		fprint(2, "%s: corrupt arena header: %r\n", name);
		return;
	}
	if(head.version != ArenaVersion4 && head.version != ArenaVersion5)
		fprint(2, "%s: warning: unknown arena version %d\n", name, head.version);
	if(len != 0 && len != head.size)
		fprint(2, "%s: warning: unexpected length %lld != %lld\n", name, head.size, len);
	if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
		fprint(2, "%s: warning: unexpected name %s\n", name, head.name);

	if(readblock(fd1, data1, HeadSize) < 0){
		fprint(2, "%s: reading header: %r\n", name);
		return;
	}
	if(unpackarenahead(&head, data) < 0){
		fprint(2, "%s: corrupt arena header: %r\n", name);
		return;
	}
	if(head.version != ArenaVersion4 && head.version != ArenaVersion5)
		fprint(2, "%s: warning: unknown arena version %d\n", name, head.version);
	if(len != 0 && len != head.size)
		fprint(2, "%s: warning: unexpected length %lld != %lld\n", name, head.size, len);
	if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
		fprint(2, "%s: warning: unexpected name %s\n", name, head.name);

	seek(fd, -HeadSize, 1);
	seek(fd1, -HeadSize, 1);

	if(printheader(name, &head, fd) < 0)
		return;
	
	/*
	 * now we know how much to read
	 * read everything but the last block, which is special
	 */
	e = head.size;
	bs = blocksize;
	for(n = 0; n < e; n += bs){
		if(n + bs > e)
			bs = e - n;
		if(readblock(fd, data, bs) < 0){
			fprint(2, "%s: read data: %r\n", name);
			return;
		}
		if(readblock(fd1, data1, bs) < 0){
			fprint(2, "%s: read data: %r\n", name);
			return;
		}
		if(memcmp(data, data1, bs) != 0){
			print("mismatch at %llx\n", n);
			for(i=0; i<bs; i+=16){
				if(memcmp(data+i, data1+i, 16) != 0){
					snprint(buf, sizeof buf, "%llx", n+i);
					print("%s ", buf);
					for(j=0; j<16; j++){
						print(" %.2ux", data[i+j]);
						if(j == 7)
							print(" -");
					}
					print("\n");
					print("%*s ", (int)strlen(buf), "");
					for(j=0; j<16; j++){
						print(" %.2ux", data1[i+j]);
						if(j == 7)
							print(" -");
					}
					print("\n");
				}
			}
		}
	}
}