Beispiel #1
0
void
threadmain(int argc, char *argv[])
{
	uchar score[VtScoreSize];
	uchar buf[VtRootSize];
	VtConn *z;
	VtRoot root;

	ARGBEGIN{
	case 'h':
		host = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	if(argc != 5)
		usage();

	fmtinstall('V', vtscorefmt);
	fmtinstall('F', vtfcallfmt);

	strecpy(root.name, root.name+sizeof root.name, argv[0]);
	strecpy(root.type, root.type+sizeof root.type, argv[1]);
	if(vtparsescore(argv[2], nil, root.score) < 0)
		sysfatal("bad score '%s'", argv[2]);
	root.blocksize = atoi(argv[3]);
	if(vtparsescore(argv[4], nil, root.prev) < 0)
		sysfatal("bad score '%s'", argv[4]);
	vtrootpack(&root, buf);

	z = vtdial(host);
	if(z == nil)
		sysfatal("could not connect to server: %r");

	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");

	if(vtwrite(z, score, VtRootType, buf, VtRootSize) < 0)
		sysfatal("vtwrite: %r");
	if(vtsync(z) < 0)
		sysfatal("vtsync: %r");
	vthangup(z);
	print("%V\n", score);
	threadexitsall(0);
}
Beispiel #2
0
void
threadmain(int argc, char *argv[])
{
	int i, n;
	unsigned char score[VtScoreSize];
	unsigned char *buf;
	VtConn *z;
	char *host;
	VtRoot root;

	fmtinstall('F', vtfcallfmt);
	fmtinstall('V', vtscorefmt);
	quotefmtinstall();

	host = nil;
	ARGBEGIN{
	case 'h':
		host = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	if(argc == 0)
		usage();

	buf = vtmallocz(VtMaxLumpSize);

	z = vtdial(host);
	if(z == nil)
		sysfatal("could not connect to server: %r");

	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");

	for(i=0; i<argc; i++){
		if(vtparsescore(argv[i], nil, score) < 0){
			fprint(2, "cannot parse score '%s': %r\n", argv[i]);
			continue;
		}
		n = vtread(z, score, VtRootType, buf, VtMaxLumpSize);
		if(n < 0){
			fprint(2, "could not read block %V: %r\n", score);
			continue;
		}
		if(n != VtRootSize){
			fprint(2, "block %V is wrong size %d != 300\n", score, n);
			continue;
		}
		if(vtrootunpack(&root, buf) < 0){
			fprint(2, "unpacking block %V: %r\n", score);
			continue;
		}
		print("%V: %q %q %V %d %V\n", score, root.name, root.type, root.score, root.blocksize, root.prev);
	}
	vthangup(z);
	threadexitsall(0);
}
Beispiel #3
0
int
hdebug(HConnect *c)
{
	char *scorestr, *op;
	u8int score[VtScoreSize];
	
	if(hsethtml(c) < 0)
		return -1;
	hprint(&c->hout, "<h1>venti debug</h1>\n");

	op = hargstr(c, "op", "");
	if(!op[0]){
		hprint(&c->hout, "no op\n");
		return 0;
	}
	
	if(strcmp(op, "amap") == 0){
		debugamap(c);
		return 0;
	}

	if(strcmp(op, "mem") == 0){
		debugmem(c);
		return 0;
	}

	if(strcmp(op, "read") == 0){
		scorestr = hargstr(c, "score", "");
		if(vtparsescore(scorestr, nil, score) < 0){
			hprint(&c->hout, "bad score %s: %r\n", scorestr);
			return 0;
		}
		debugread(c, score);
		return 0;
	}
	
	hprint(&c->hout, "unknown op %s", op);
	return 0;
}
Beispiel #4
0
void
main(int argc, char *argv[])
{
	int type, n;
	unsigned char score[VtScoreSize];
	unsigned char *buf;
	char *prefix;

	fmtinstall('F', vtfcallfmt);
	fmtinstall('V', vtscorefmt);

	type = -1;
	ARGBEGIN{
	case 'V':
		chattyventi++;
		break;
	case 'f':
		fast = 1;
		break;
	case 'i':
		if(rewrite)
			usage();
		ignoreerrors = 1;
		break;
	case 'm':
		scoretree = mkavltree(scoretreecmp);
		break;
	case 'r':
		if(ignoreerrors)
			usage();
		rewrite = 1;
		break;
	case 't':
		type = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	default:
		usage();
		break;
	}ARGEND

	if(argc != 3)
		usage();

	if(vtparsescore(argv[2], &prefix, score) < 0)
		sysfatal("could not parse score: %r");

	buf = vtmallocz(VtMaxLumpSize);

	zsrc = vtdial(argv[0]);
	if(zsrc == nil)
		sysfatal("could not dial src server: %r");
	if(vtconnect(zsrc) < 0)
		sysfatal("vtconnect src: %r");

	zdst = vtdial(argv[1]);
	if(zdst == nil)
		sysfatal("could not dial dst server: %r");
	if(vtconnect(zdst) < 0)
		sysfatal("vtconnect dst: %r");

	if(type != -1){
		n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
		if(n < 0)
			sysfatal("could not read block: %r");
	}else{
		for(type=0; type<VtMaxType; type++){
			n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
			if(n >= 0)
				break;
		}
		if(type == VtMaxType)
			sysfatal("could not find block %V of any type", score);
	}

	walk(score, type, VtDirType);
	if(changes)
		print("%s:%V (%d pointers rewritten)\n", prefix, score, changes);

	if(verbose)
		print("%d skipped, %d written\n", nskip, nwrite);

	if(vtsync(zdst) < 0)
		sysfatal("could not sync dst server: %r");

	exits(0);
}
Beispiel #5
0
void
threadmain(int argc, char *argv[])
{
	int type, n;
	uchar score[VtScoreSize];
	uchar *buf;
	VtConn *z;
	char *host;

	fmtinstall('F', vtfcallfmt);
	fmtinstall('V', vtscorefmt);

	host = nil;
	type = -1;
	ARGBEGIN{
	case 'h':
		host = EARGF(usage());
		break;
	case 't':
		type = atoi(EARGF(usage()));
		break;
	default:
		usage();
		break;
	}ARGEND

	if(argc != 1)
		usage();

	if(vtparsescore(argv[0], nil, score) < 0)
		sysfatal("could not parse score '%s': %r", argv[0]);

	buf = vtmallocz(VtMaxLumpSize);

	z = vtdial(host);
	if(z == nil)
		sysfatal("could not connect to server: %r");

	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");

	if(type == -1){
		n = -1;
		for(type=0; type<VtMaxType; type++){
			n = vtread(z, score, type, buf, VtMaxLumpSize);
			if(n >= 0){
				fprint(2, "venti/read%s%s %V %d\n", host ? " -h" : "", host ? host : "",
					score, type);
				break;
			}
		}
	}else
		n = vtread(z, score, type, buf, VtMaxLumpSize);

	vthangup(z);
	if(n < 0)
		sysfatal("could not read block: %r");
	if(write(1, buf, n) != n)
		sysfatal("write: %r");
	threadexitsall(0);
}
Beispiel #6
0
void
threadmain(int argc, char *argv[])
{
	int n;
	uchar score[VtScoreSize];
	uchar *buf;
	char *host, *type;
	vlong off;
	VtEntry e;
	VtRoot root;
	VtCache *c;
	VtConn *z;
	VtFile *f;

	quotefmtinstall();
	fmtinstall('F', vtfcallfmt);
	fmtinstall('V', vtscorefmt);

	host = nil;
	ARGBEGIN{
	case 'V':
		chattyventi++;
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'v':
		chatty++;
		break;
	default:
		usage();
		break;
	}ARGEND

	if(argc != 1)
		usage();

	type = nil;
	if(vtparsescore(argv[0], &type, score) < 0)
		sysfatal("could not parse score '%s': %r", argv[0]);
	if(type == nil || strcmp(type, "file") != 0)
		sysfatal("bad score - not file:...");

	buf = vtmallocz(VtMaxLumpSize);

	z = vtdial(host);
	if(z == nil)
		sysfatal("could not connect to server: %r");

	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");

	// root block ...
	n = vtread(z, score, VtRootType, buf, VtMaxLumpSize);
	if(n < 0)
		sysfatal("could not read root %V: %r", score);
	if(n != VtRootSize)
		sysfatal("root block %V is wrong size %d != %d", score, n, VtRootSize);
	if(vtrootunpack(&root, buf) < 0)
		sysfatal("unpacking root block %V: %r", score);
	if(strcmp(root.type, "file") != 0)
		sysfatal("bad root type %q (not 'file')", root.type);
	if(chatty)
		fprint(2, "%V: %q %q %V %d %V\n",
			score, root.name, root.type,
			root.score, root.blocksize, root.prev);

	// ... points at entry block
	n = vtread(z, root.score, VtDirType, buf, VtMaxLumpSize);
	if(n < 0)
		sysfatal("could not read entry %V: %r", root.score);
	if(n != VtEntrySize)
		sysfatal("dir block %V is wrong size %d != %d", root.score, n, VtEntrySize);
	if(vtentryunpack(&e, buf, 0) < 0)
		sysfatal("unpacking dir block %V: %r", root.score);
	if((e.type&VtTypeBaseMask) != VtDataType)
		sysfatal("not a single file");

	// open and read file
	c = vtcachealloc(z, root.blocksize*32);
	if(c == nil)
		sysfatal("vtcachealloc: %r");
	f = vtfileopenroot(c, &e);
	if(f == nil)
		sysfatal("vtfileopenroot: %r");
	off = 0;
	vtfilelock(f, VtOREAD);
	while((n = vtfileread(f, buf, VtMaxLumpSize, off)) > 0){
		write(1, buf, n);
		off += n;
	}
	threadexitsall(0);
}
Beispiel #7
0
void
threadmain(int argc, char **argv)
{
	char *pref, *mountname, *mountplace;
	uchar score[VtScoreSize], prev[VtScoreSize];
	int i, fd, csize;
	vlong bsize;
	Tm tm;
	VtEntry e;
	VtBlock *b;
	VtCache *c;
	VtRoot root;
	char *tmp, *tmpnam;

	fmtinstall('F', vtfcallfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('T', timefmt);
	fmtinstall('V', vtscorefmt);

	mountname = sysname();
	mountplace = nil;
	ARGBEGIN{
	default:
		usage();
		break;
	case 'D':
		debug++;
		break;
	case 'V':
		chattyventi = 1;
		break;
	case 'f':
		fastwrites = 1;
		break;
	case 'i':
		incremental = 1;
		break;
	case 'm':
		mountname = EARGF(usage());
		break;
	case 'M':
		mountplace = EARGF(usage());
		i = strlen(mountplace);
		if(i > 0 && mountplace[i-1] == '/')
			mountplace[i-1] = 0;
		break;
	case 'n':
		nop = 1;
		break;
	case 's':
		statustime = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	case 'w':
		nwritethread = atoi(EARGF(usage()));
		break;
	}ARGEND

	if(argc != 1 && argc != 2)
		usage();

	if(statustime)
		print("# %T vbackup %s %s\n", argv[0], argc>=2 ? argv[1] : "");

	/*
	 * open fs
	 */
	if((disk = diskopenfile(argv[0])) == nil)
		sysfatal("diskopen: %r");
	if((disk = diskcache(disk, 32768, 2*MAXQ+16)) == nil)
		sysfatal("diskcache: %r");
	if((fsys = fsysopen(disk)) == nil)
		sysfatal("fsysopen: %r");

	/*
	 * connect to venti
	 */
	if((z = vtdial(nil)) == nil)
		sysfatal("vtdial: %r");
	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");

	/*
	 * set up venti block cache
	 */
	zero = vtmallocz(fsys->blocksize);
	bsize = fsys->blocksize;
	csize = 50;	/* plenty; could probably do with 5 */

	if(verbose)
		fprint(2, "cache %d blocks\n", csize);
	c = vtcachealloc(z, bsize*csize);
	zcache = c;

	/*
	 * parse starting score
	 */
	memset(prev, 0, sizeof prev);
	if(argc == 1){
		vfile = vtfilecreateroot(c, (fsys->blocksize/VtScoreSize)*VtScoreSize,
			fsys->blocksize, VtDataType);
		if(vfile == nil)
			sysfatal("vtfilecreateroot: %r");
		vtfilelock(vfile, VtORDWR);
		if(vtfilewrite(vfile, zero, 1, bsize*fsys->nblock-1) != 1)
			sysfatal("vtfilewrite: %r");
		if(vtfileflush(vfile) < 0)
			sysfatal("vtfileflush: %r");
	}else{
		if(vtparsescore(argv[1], &pref, score) < 0)
			sysfatal("bad score: %r");
		if(pref!=nil && strcmp(pref, fsys->type) != 0)
			sysfatal("score is %s but fsys is %s", pref, fsys->type);
		b = vtcacheglobal(c, score, VtRootType, VtRootSize);
		if(b){
			if(vtrootunpack(&root, b->data) < 0)
				sysfatal("bad root: %r");
			if(strcmp(root.type, fsys->type) != 0)
				sysfatal("root is %s but fsys is %s", root.type, fsys->type);
			memmove(prev, score, VtScoreSize);
			memmove(score, root.score, VtScoreSize);
			vtblockput(b);
		}
		b = vtcacheglobal(c, score, VtDirType, VtEntrySize);
		if(b == nil)
			sysfatal("vtcacheglobal %V: %r", score);
		if(vtentryunpack(&e, b->data, 0) < 0)
			sysfatal("%V: vtentryunpack failed", score);
		if(verbose)
			fprint(2, "entry: size %llud psize %d dsize %d\n",
				e.size, e.psize, e.dsize);
		vtblockput(b);
		if((vfile = vtfileopenroot(c, &e)) == nil)
			sysfatal("vtfileopenroot: %r");
		vtfilelock(vfile, VtORDWR);
		if(e.dsize != bsize)
			sysfatal("file system block sizes don't match %d %lld", e.dsize, bsize);
		if(e.size != fsys->nblock*bsize)
			sysfatal("file system block counts don't match %lld %lld", e.size, fsys->nblock*bsize);
	}

	tmpnam = nil;
	if(incremental){
		if(vtfilegetentry(vfile, &e) < 0)
			sysfatal("vtfilegetentry: %r");
		if((vscores = vtfileopenroot(c, &e)) == nil)
			sysfatal("vtfileopenroot: %r");
		vtfileunlock(vfile);
	}else{
		/*
		 * write scores of blocks into temporary file
		 */
		if((tmp = getenv("TMP")) != nil){
			/* okay, good */
		}else if(access("/var/tmp", 0) >= 0)
			tmp = "/var/tmp";
		else
			tmp = "/tmp";
		tmpnam = smprint("%s/vbackup.XXXXXX", tmp);
		if(tmpnam == nil)
			sysfatal("smprint: %r");
	
		if((fd = opentemp(tmpnam, ORDWR|ORCLOSE)) < 0)
			sysfatal("opentemp %s: %r", tmpnam);
		if(statustime)
			print("# %T reading scores into %s\n", tmpnam);
		if(verbose)
			fprint(2, "read scores into %s...\n", tmpnam);
	
		Binit(&bscores, fd, OWRITE);
		for(i=0; i<fsys->nblock; i++){
			if(vtfileblockscore(vfile, i, score) < 0)
				sysfatal("vtfileblockhash %d: %r", i);
			if(Bwrite(&bscores, score, VtScoreSize) != VtScoreSize)
				sysfatal("Bwrite: %r");
		}
		Bterm(&bscores);
		vtfileunlock(vfile);
	
		/*
		 * prep scores for rereading
		 */
		seek(fd, 0, 0);
		Binit(&bscores, fd, OREAD);
	}

	/*
	 * start the main processes 
	 */
	if(statustime)
		print("# %T starting procs\n");
	qcmp = qalloc();
	qventi = qalloc();

	rlock(&endlk);
	proccreate(fsysproc, nil, STACK);
	rlock(&endlk);
	proccreate(ventiproc, nil, STACK);
	rlock(&endlk);
	proccreate(cmpproc, nil, STACK);
	if(statustime){
		rlock(&endlk);
		proccreate(statusproc, nil, STACK);
	}

	/*
	 * wait for processes to finish
	 */
	wlock(&endlk);
	
	qfree(qcmp);
	qfree(qventi);

	if(statustime)
		print("# %T procs exited: %d of %d %d-byte blocks changed, "
			"%d read, %d written, %d skipped, %d copied\n",
			nchange, fsys->nblock, fsys->blocksize,
			vtcachenread, vtcachenwrite, nskip, vtcachencopy);

	/*
	 * prepare root block
	 */
	if(incremental)
		vtfileclose(vscores);
	vtfilelock(vfile, -1);
	if(vtfileflush(vfile) < 0)
		sysfatal("vtfileflush: %r");
	if(vtfilegetentry(vfile, &e) < 0)
		sysfatal("vtfilegetentry: %r");
	vtfileunlock(vfile);
	vtfileclose(vfile);

	b = vtcacheallocblock(c, VtDirType, VtEntrySize);
	if(b == nil)
		sysfatal("vtcacheallocblock: %r");
	vtentrypack(&e, b->data, 0);
	if(vtblockwrite(b) < 0)
		sysfatal("vtblockwrite: %r");

	memset(&root, 0, sizeof root);
	strecpy(root.name, root.name+sizeof root.name, argv[0]);
	strecpy(root.type, root.type+sizeof root.type, fsys->type);
	memmove(root.score, b->score, VtScoreSize);
	root.blocksize = fsys->blocksize;
	memmove(root.prev, prev, VtScoreSize);
	vtblockput(b);

	b = vtcacheallocblock(c, VtRootType, VtRootSize);
	if(b == nil)
		sysfatal("vtcacheallocblock: %r");
	vtrootpack(&root, b->data);
	if(vtblockwrite(b) < 0)
		sysfatal("vtblockwrite: %r");

	tm = *localtime(time(0));
	tm.year += 1900;
	tm.mon++;
	if(mountplace == nil)
		mountplace = guessmountplace(argv[0]);
	print("mount /%s/%d/%02d%02d%s %s:%V %d/%02d%02d/%02d%02d\n",
		mountname, tm.year, tm.mon, tm.mday, 
		mountplace,
		root.type, b->score,
		tm.year, tm.mon, tm.mday, tm.hour, tm.min);
	print("# %T %s %s:%V\n", argv[0], root.type, b->score);
	if(statustime)
		print("# %T venti sync\n");
	vtblockput(b);
	if(vtsync(z) < 0)
		sysfatal("vtsync: %r");
	if(statustime)
		print("# %T synced\n");
	
	fsysclose(fsys);
	diskclose(disk);
	vtcachefree(zcache);

	// Vtgoodbye hangs on Linux - not sure why.
	// Probably vtfcallrpc doesn't quite get the
	// remote hangup right.  Also probably related
	// to the vtrecvproc problem below.
	// vtgoodbye(z);

	// Leak here, because I can't seem to make
	// the vtrecvproc exit.
	// vtfreeconn(z);

	free(tmpnam);
	z = nil;
	zcache = nil;
	fsys = nil;
	disk = nil;
	threadexitsall(nil);
}
Beispiel #8
0
static int
diskarenaclump(HConnect *c, Arena *arena, vlong off, char *scorestr)
{
	uchar *blk, *blk2;
	Clump cl;
	char err[ERRMAX];
	uchar xscore[VtScoreSize], score[VtScoreSize];
	Unwhack uw;
	int n;
	
	if(scorestr){
		if(vtparsescore(scorestr, nil, score) < 0){
			hprint(&c->hout, "bad score %s: %r\n", scorestr);
			return -1;
		}
		if(off < 0){
			off = findintoc(c, arena, score);
			if(off < 0){
				hprint(&c->hout, "score %V not found in arena %s\n", score, arena->name);
				return -1;
			}
			hprint(&c->hout, "score %V at %#llx\n", score, off);
		}
	}else
		memset(score, 0, sizeof score);

	if(off < 0){
		hprint(&c->hout, "bad offset %#llx\n", off);
		return -1;
	}
	
	off += arena->base;

	blk = vtmalloc(ClumpSize + VtMaxLumpSize);
	if(readpart(arena->part, off, blk, ClumpSize + VtMaxLumpSize) != ClumpSize + VtMaxLumpSize){
		hprint(&c->hout, "reading at %#llx: %r\n", off);
		vtfree(blk);
		return -1;
	}

	if(unpackclump(&cl, blk, arena->clumpmagic) < 0){
		hprint(&c->hout, "unpackclump: %r\n<br>");
		rerrstr(err, sizeof err);
		if(strstr(err, "magic")){
			hprint(&c->hout, "trying again with magic=%#ux<br>\n", U32GET(blk));
			if(unpackclump(&cl, blk, U32GET(blk)) < 0){
				hprint(&c->hout, "unpackclump: %r\n<br>\n");
				goto error;
			}
		}else
			goto error;
	}

	hprint(&c->hout, "<pre>type=%d size=%d uncsize=%d score=%V\n", cl.info.type, cl.info.size, cl.info.uncsize, cl.info.score);
	hprint(&c->hout, "encoding=%d creator=%d time=%d %s</pre>\n", cl.encoding, cl.creator, cl.time, fmttime(err, cl.time));
	
	if(cl.info.type == VtCorruptType)
		hprint(&c->hout, "clump is marked corrupt<br>\n");
	
	if(cl.info.size >= VtMaxLumpSize){
		hprint(&c->hout, "clump too big\n");
		goto error;
	}
	
	switch(cl.encoding){
	case ClumpECompress:
		blk2 = vtmalloc(VtMaxLumpSize);
		unwhackinit(&uw);
		n = unwhack(&uw, blk2, cl.info.uncsize, blk+ClumpSize, cl.info.size);
		if(n < 0){
			hprint(&c->hout, "decompression failed\n");
			vtfree(blk2);
			goto error;
		}
		if(n != cl.info.uncsize){
			hprint(&c->hout, "got wrong amount: %d wanted %d\n", n, cl.info.uncsize);
			// hhex(blk2, n);
			vtfree(blk2);
			goto error;
		}
		scoremem(xscore, blk2, cl.info.uncsize);
		vtfree(blk2);
		break;
	case ClumpENone:
		scoremem(xscore, blk+ClumpSize, cl.info.size);
		break;
	}
	
	hprint(&c->hout, "score=%V<br>\n", xscore);
	if(scorestr && scorecmp(score, xscore) != 0)
		hprint(&c->hout, "score does NOT match expected %V\n", score);

	vtfree(blk);
	return 0;

error:
	// hhex(blk, ClumpSize + VtMaxLumpSize);
	vtfree(blk);
	return -1;
}