Browse Source

Plan 9 from Bell Labs 2008-04-04

David du Colombier 16 years ago
parent
commit
cb1f1824ab

+ 3 - 3
dist/replica/_plan9.db

@@ -14365,7 +14365,7 @@ sys/src/cmd/venti/readlist.c - 664 sys sys 1177189435 1934
 sys/src/cmd/venti/ro.c - 664 sys sys 1177189435 1886
 sys/src/cmd/venti/root.c - 664 sys sys 1177189435 1329
 sys/src/cmd/venti/srv - 20000000775 sys sys 1189020012 0
-sys/src/cmd/venti/srv/arena.c - 664 sys sys 1191257299 20137
+sys/src/cmd/venti/srv/arena.c - 664 sys sys 1207253133 20156
 sys/src/cmd/venti/srv/arenas.c - 664 sys sys 1178160303 8039
 sys/src/cmd/venti/srv/bloom.c - 664 sys sys 1196369124 4445
 sys/src/cmd/venti/srv/buildbuck.c - 664 sys sys 1177189435 2837
@@ -14377,7 +14377,7 @@ sys/src/cmd/venti/srv/clumpstats.c - 664 sys sys 1142736351 2234
 sys/src/cmd/venti/srv/cmparenas.c - 664 sys sys 1177189435 7215
 sys/src/cmd/venti/srv/conf.rc - 775 sys sys 1189304120 1416
 sys/src/cmd/venti/srv/config.c - 664 sys sys 1191257289 5659
-sys/src/cmd/venti/srv/conv.c - 664 sys sys 1191257291 14072
+sys/src/cmd/venti/srv/conv.c - 664 sys sys 1207253152 15161
 sys/src/cmd/venti/srv/dat.h - 664 sys sys 1196369171 19088
 sys/src/cmd/venti/srv/dcache.c - 664 sys sys 1196369150 15782
 sys/src/cmd/venti/srv/disksched.c - 664 sys sys 1193791117 2127
@@ -14411,7 +14411,7 @@ sys/src/cmd/venti/srv/printindex.c - 664 sys sys 1142736355 1746
 sys/src/cmd/venti/srv/printmap.c - 664 sys sys 1142736355 542
 sys/src/cmd/venti/srv/rdarena.c - 664 sys sys 1202925159 1695
 sys/src/cmd/venti/srv/readifile.c - 664 sys sys 1177534667 411
-sys/src/cmd/venti/srv/reseal.c - 664 sys sys 1177189438 6682
+sys/src/cmd/venti/srv/reseal.c - 664 sys sys 1207253699 6520
 sys/src/cmd/venti/srv/round.c - 664 sys sys 1142736355 1577
 sys/src/cmd/venti/srv/score.c - 664 sys sys 1178160305 740
 sys/src/cmd/venti/srv/sortientry.c - 664 sys sys 1177189439 8325

+ 3 - 3
dist/replica/plan9.db

@@ -14365,7 +14365,7 @@ sys/src/cmd/venti/readlist.c - 664 sys sys 1177189435 1934
 sys/src/cmd/venti/ro.c - 664 sys sys 1177189435 1886
 sys/src/cmd/venti/root.c - 664 sys sys 1177189435 1329
 sys/src/cmd/venti/srv - 20000000775 sys sys 1189020012 0
-sys/src/cmd/venti/srv/arena.c - 664 sys sys 1191257299 20137
+sys/src/cmd/venti/srv/arena.c - 664 sys sys 1207253133 20156
 sys/src/cmd/venti/srv/arenas.c - 664 sys sys 1178160303 8039
 sys/src/cmd/venti/srv/bloom.c - 664 sys sys 1196369124 4445
 sys/src/cmd/venti/srv/buildbuck.c - 664 sys sys 1177189435 2837
@@ -14377,7 +14377,7 @@ sys/src/cmd/venti/srv/clumpstats.c - 664 sys sys 1142736351 2234
 sys/src/cmd/venti/srv/cmparenas.c - 664 sys sys 1177189435 7215
 sys/src/cmd/venti/srv/conf.rc - 775 sys sys 1189304120 1416
 sys/src/cmd/venti/srv/config.c - 664 sys sys 1191257289 5659
-sys/src/cmd/venti/srv/conv.c - 664 sys sys 1191257291 14072
+sys/src/cmd/venti/srv/conv.c - 664 sys sys 1207253152 15161
 sys/src/cmd/venti/srv/dat.h - 664 sys sys 1196369171 19088
 sys/src/cmd/venti/srv/dcache.c - 664 sys sys 1196369150 15782
 sys/src/cmd/venti/srv/disksched.c - 664 sys sys 1193791117 2127
@@ -14411,7 +14411,7 @@ sys/src/cmd/venti/srv/printindex.c - 664 sys sys 1142736355 1746
 sys/src/cmd/venti/srv/printmap.c - 664 sys sys 1142736355 542
 sys/src/cmd/venti/srv/rdarena.c - 664 sys sys 1202925159 1695
 sys/src/cmd/venti/srv/readifile.c - 664 sys sys 1177534667 411
-sys/src/cmd/venti/srv/reseal.c - 664 sys sys 1177189438 6682
+sys/src/cmd/venti/srv/reseal.c - 664 sys sys 1207253699 6520
 sys/src/cmd/venti/srv/round.c - 664 sys sys 1142736355 1577
 sys/src/cmd/venti/srv/score.c - 664 sys sys 1178160305 740
 sys/src/cmd/venti/srv/sortientry.c - 664 sys sys 1177189439 8325

+ 3 - 0
dist/replica/plan9.log

@@ -18937,3 +18937,6 @@
 1207166405 11 c 386/bin/venti/syncindex - 775 sys sys 1207166156 267073
 1207166405 12 c 386/bin/venti/venti - 775 sys sys 1207166167 705792
 1207166405 13 c 386/bin/venti/wrarena - 775 sys sys 1207166173 284042
+1207252804 0 c sys/src/cmd/venti/srv/arena.c - 664 sys sys 1207253133 20156
+1207252804 1 c sys/src/cmd/venti/srv/conv.c - 664 sys sys 1207253152 15161
+1207254604 0 c sys/src/cmd/venti/srv/reseal.c - 664 sys sys 1207253699 6520

+ 1 - 0
sys/src/cmd/venti/srv/arena.c

@@ -308,6 +308,7 @@ writeaclump(Arena *arena, Clump *c, u8int *clbuf)
 		if(!arena->memstats.sealed){
 			logerr(EOk, "seal memstats %s", arena->name);
 			arena->memstats.sealed = 1;
+			wbarena(arena);
 		}
 		qunlock(&arena->lock);
 		return TWID64;

+ 26 - 0
sys/src/cmd/venti/srv/conv.c

@@ -177,6 +177,27 @@ unpackarena(Arena *arena, u8int *buf)
 		p += U64Size;
 		arena->memstats.sealed = U8GET(p);
 		p += U8Size;
+		
+		/*
+		 * 2008/4/2
+		 * Packarena (below) used to have a bug in which it would
+		 * not zero out any existing extension fields when writing
+		 * the arena metadata.  This would manifest itself as arenas
+		 * with arena->diskstats.sealed == 1 but arena->memstats.sealed == 0
+		 * after a server restart.  Because arena->memstats.sealed wouldn't
+		 * be set, the server might try to fit another block into the arena
+		 * (and succeed), violating the append-only structure of the log
+		 * and invalidating any already-computed seal on the arena.
+		 *
+		 * It might end up that other fields in arena->memstats end up
+		 * behind arena->diskstats too, but that would be considerably
+		 * more rare, and the bug is fixed now.  The case we need to
+		 * handle is just the sealed mismatch.
+		 *
+		 * If we encounter such a bogus arena, fix the sealed field.
+		 */
+		if(arena->diskstats.sealed)
+			arena->memstats.sealed = 1;
 	}else
 		arena->memstats = arena->diskstats;
 	if(buf + sz != p)
@@ -262,6 +283,11 @@ _packarena(Arena *arena, u8int *buf, int forceext)
 		p += U64Size;
 		U8PUT(p, arena->memstats.sealed);
 		p += U8Size;
+	}else{
+		/* Clear any extension fields already on disk. */
+		memset(p, 0, ArenaSize5a - ArenaSize5);
+		p += ArenaSize5a - ArenaSize5;
+		sz += ArenaSize5a - ArenaSize5;
 	}
 
 	if(buf + sz != p)

+ 35 - 46
sys/src/cmd/venti/srv/reseal.c

@@ -2,28 +2,29 @@
 #include "dat.h"
 #include "fns.h"
 
-static int	verbose;
-static int	fd;
 static uchar	*data;
 static uchar	*data1;
 static int	blocksize;
 static int	sleepms;
+static int	fd;
+static int	force;
+static vlong	offset0;
 
 void
 usage(void)
 {
-	fprint(2, "usage: reseal [-b blocksize] [-s ms] [-v] arenapart1 [name...]]\n");
+	fprint(2, "usage: reseal [-f] [-b blocksize] [-s ms] arenapart1 [name...]]\n");
 	threadexitsall(0);
 }
 
 static int
-pwriteblock(int fd, uchar *buf, int n, vlong off)
+pwriteblock(uchar *buf, int n, vlong off)
 {
 	int nr, m;
 
 	for(nr = 0; nr < n; nr += m){
 		m = n - nr;
-		m = pwrite(fd, &buf[nr], m, off+nr);
+		m = pwrite(fd, &buf[nr], m, offset0+off+nr);
 		if(m <= 0)
 			return -1;
 	}
@@ -31,30 +32,13 @@ pwriteblock(int fd, uchar *buf, int n, vlong off)
 }
 
 static int
-preadblock(int fd, uchar *buf, int n, vlong off)
-{
-	int nr, m;
-
-	for(nr = 0; nr < n; nr += m){
-		m = n - nr;
-		m = pread(fd, &buf[nr], m, off+nr);
-		if(m <= 0){
-			if(m == 0)
-				werrstr("early eof");
-			return -1;
-		}
-	}
-	return 0;
-}
-
-static int
-readblock(int fd, uchar *buf, int n)
+preadblock(uchar *buf, int n, vlong off)
 {
 	int nr, m;
 
 	for(nr = 0; nr < n; nr += m){
 		m = n - nr;
-		m = read(fd, &buf[nr], m);
+		m = pread(fd, &buf[nr], m, offset0+off+nr);
 		if(m <= 0){
 			if(m == 0)
 				werrstr("early eof");
@@ -65,9 +49,9 @@ readblock(int fd, uchar *buf, int n)
 }
 
 static int
-loadheader(char *name, ArenaHead *head, Arena *arena, int fd, vlong off)
+loadheader(char *name, ArenaHead *head, Arena *arena, vlong off)
 {
-	if(preadblock(fd, data, head->blocksize, off + head->size - head->blocksize) < 0){
+	if(preadblock(data, head->blocksize, off + head->size - head->blocksize) < 0){
 		fprint(2, "%s: reading arena tail: %r\n", name);
 		return -1;
 	}
@@ -90,7 +74,7 @@ loadheader(char *name, ArenaHead *head, Arena *arena, int fd, vlong off)
 uchar zero[VtScoreSize];
 
 static int
-verify(int fd, Arena *arena, void *data, uchar *newscore)
+verify(Arena *arena, void *data, uchar *newscore)
 {
 	vlong e, bs, n, o;
 	DigestState ds, ds1;
@@ -105,7 +89,7 @@ verify(int fd, Arena *arena, void *data, uchar *newscore)
 	bs = arena->blocksize;
 	memset(&ds, 0, sizeof ds);
 	for(n = 0; n < e; n += bs){
-		if(preadblock(fd, data, bs, o + n) < 0){
+		if(preadblock(data, bs, o + n) < 0){
 			werrstr("read: %r");
 			return -1;
 		}
@@ -115,7 +99,7 @@ verify(int fd, Arena *arena, void *data, uchar *newscore)
 	}
 	
 	/* last block */
-	if(preadblock(fd, data, arena->blocksize, o + e) < 0){
+	if(preadblock(data, arena->blocksize, o + e) < 0){
 		werrstr("read: %r");
 		return -1;
 	}
@@ -123,8 +107,11 @@ verify(int fd, Arena *arena, void *data, uchar *newscore)
 	sha1(data, bs - VtScoreSize, nil, &ds);
 	sha1(zero, VtScoreSize, score, &ds);
 	if(scorecmp(score, arena->score) != 0){
-		werrstr("score mismatch: %V != %V", score, arena->score);
-		return -1;
+		if(!force){
+			werrstr("score mismatch: %V != %V", score, arena->score);
+			return -1;
+		}
+		fprint(2, "warning: score mismatch %V != %V\n", score, arena->score);
 	}
 	
 	/* prepare new last block */
@@ -154,7 +141,7 @@ resealarena(char *name, vlong len)
 	/*
 	 * read a little bit, which will include the header
 	 */
-	if(preadblock(fd, data, HeadSize, off) < 0){
+	if(preadblock(data, HeadSize, off) < 0){
 		fprint(2, "%s: reading header: %r\n", name);
 		return;
 	}
@@ -169,7 +156,7 @@ resealarena(char *name, vlong len)
 	if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
 		fprint(2, "%s: warning: unexpected name %s\n", name, head.name);
 
-	if(loadheader(name, &head, &arena, fd, off) < 0)
+	if(loadheader(name, &head, &arena, off) < 0)
 		return;
 	
 	if(!arena.diskstats.sealed){
@@ -177,20 +164,19 @@ resealarena(char *name, vlong len)
 		return;
 	}
 	
-	if(verify(fd, &arena, data, newscore) < 0){
+	if(verify(&arena, data, newscore) < 0){
 		fprint(2, "%s: failed to verify before reseal: %r\n", name);
 		return;
 	}
-	fprint(2, "%s: verified: %V\n", name, arena.score);
 	
-	if(pwriteblock(fd, data, arena.blocksize, arena.base + arena.size) < 0){
+	if(pwriteblock(data, arena.blocksize, arena.base + arena.size) < 0){
 		fprint(2, "%s: writing new tail: %r\n", name);
 		return;
 	}
 	scorecp(arena.score, newscore);
 	fprint(2, "%s: resealed: %V\n", name, newscore);
 
-	if(verify(fd, &arena, data, newscore) < 0){
+	if(verify(&arena, data, newscore) < 0){
 		fprint(2, "%s: failed to verify after reseal!: %r\n", name);
 		return;
 	}
@@ -216,11 +202,11 @@ shouldcheck(char *name, char **s, int n)
 }
 
 char *
-readap(int fd, ArenaPart *ap)
+readap(ArenaPart *ap)
 {
 	char *table;
 	
-	if(preadblock(fd, data, 8192, PartBlank) < 0)
+	if(preadblock(data, 8192, PartBlank) < 0)
 		sysfatal("read arena part header: %r");
 	if(unpackarenapart(ap, data) < 0)
 		sysfatal("corrupted arena part header: %r");
@@ -229,7 +215,7 @@ readap(int fd, ArenaPart *ap)
 	ap->tabbase = (PartBlank+HeadSize+ap->blocksize-1)&~(ap->blocksize-1);
 	ap->tabsize = ap->arenabase - ap->tabbase;
 	table = malloc(ap->tabsize+1);
-	if(preadblock(fd, (uchar*)table, ap->tabsize, ap->tabbase) < 0)
+	if(preadblock((uchar*)table, ap->tabsize, ap->tabbase) < 0)
 		sysfatal("reading arena part directory: %r");
 	table[ap->tabsize] = 0;
 	return table;
@@ -242,6 +228,7 @@ threadmain(int argc, char *argv[])
 	char *p, *q, *table, *f[10], line[256];
 	vlong start, stop;
 	ArenaPart ap;
+	Part *part;
 	
 	ventifmtinstall();
 	blocksize = MaxIoSize;
@@ -249,12 +236,12 @@ threadmain(int argc, char *argv[])
 	case 'b':
 		blocksize = unittoull(EARGF(usage()));
 		break;
+	case 'f':
+		force = 1;
+		break;
 	case 's':
 		sleepms = atoi(EARGF(usage()));
 		break;
-	case 'v':
-		verbose++;
-		break;
 	default:
 		usage();
 		break;
@@ -264,10 +251,12 @@ threadmain(int argc, char *argv[])
 		usage();
 
 	data = vtmalloc(blocksize);
-	if((fd = open(argv[0], ORDWR)) < 0)
-		sysfatal("open %s: %r", argv[0]);
+	if((part = initpart(argv[0], ORDWR)) == nil)
+		sysfatal("open partition %s: %r", argv[0]);
+	fd = part->fd;
+	offset0 = part->offset;
 
-	table = readap(fd, &ap);
+	table = readap(&ap);
 
 	nline = atoi(table);
 	p = strchr(table, '\n');