merge
This commit is contained in:
commit
9f8a101a7c
5 changed files with 65 additions and 47 deletions
|
|
@ -23,6 +23,8 @@ bin/unmount
|
||||||
bin/vwhois
|
bin/vwhois
|
||||||
bin/vmount
|
bin/vmount
|
||||||
bin/yesterday
|
bin/yesterday
|
||||||
|
mail/lib/qmail
|
||||||
|
mail/lib/remotemail
|
||||||
man/mkindex
|
man/mkindex
|
||||||
tmac/tmac.an
|
tmac/tmac.an
|
||||||
tmac/tmac.anhtml
|
tmac/tmac.anhtml
|
||||||
|
|
|
||||||
|
|
@ -308,6 +308,7 @@ writeaclump(Arena *arena, Clump *c, u8int *clbuf)
|
||||||
if(!arena->memstats.sealed){
|
if(!arena->memstats.sealed){
|
||||||
logerr(EOk, "seal memstats %s", arena->name);
|
logerr(EOk, "seal memstats %s", arena->name);
|
||||||
arena->memstats.sealed = 1;
|
arena->memstats.sealed = 1;
|
||||||
|
wbarena(arena);
|
||||||
}
|
}
|
||||||
qunlock(&arena->lock);
|
qunlock(&arena->lock);
|
||||||
return TWID64;
|
return TWID64;
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,27 @@ unpackarena(Arena *arena, u8int *buf)
|
||||||
p += U64Size;
|
p += U64Size;
|
||||||
arena->memstats.sealed = U8GET(p);
|
arena->memstats.sealed = U8GET(p);
|
||||||
p += U8Size;
|
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
|
}else
|
||||||
arena->memstats = arena->diskstats;
|
arena->memstats = arena->diskstats;
|
||||||
if(buf + sz != p)
|
if(buf + sz != p)
|
||||||
|
|
@ -262,6 +283,11 @@ _packarena(Arena *arena, u8int *buf, int forceext)
|
||||||
p += U64Size;
|
p += U64Size;
|
||||||
U8PUT(p, arena->memstats.sealed);
|
U8PUT(p, arena->memstats.sealed);
|
||||||
p += U8Size;
|
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)
|
if(buf + sz != p)
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,7 @@ icachedirty(u32int lo, u32int hi, u64int limit)
|
||||||
trace(TraceProc, "icachedirty enter");
|
trace(TraceProc, "icachedirty enter");
|
||||||
qlock(&icache.lock);
|
qlock(&icache.lock);
|
||||||
for(ie = icache.dirty.next; ie != &icache.dirty; ie=ie->next){
|
for(ie = icache.dirty.next; ie != &icache.dirty; ie=ie->next){
|
||||||
if(ie->state == IEDirty && ie->ia.addr < limit){
|
if(ie->state == IEDirty && ie->ia.addr <= limit){
|
||||||
h = hashbits(ie->score, 32);
|
h = hashbits(ie->score, 32);
|
||||||
if(lo <= h && h <= hi){
|
if(lo <= h && h <= hi){
|
||||||
ie->nextdirty = dirty;
|
ie->nextdirty = dirty;
|
||||||
|
|
|
||||||
|
|
@ -2,28 +2,29 @@
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
|
|
||||||
static int verbose;
|
|
||||||
static int fd;
|
|
||||||
static uchar *data;
|
static uchar *data;
|
||||||
static uchar *data1;
|
static uchar *data1;
|
||||||
static int blocksize;
|
static int blocksize;
|
||||||
static int sleepms;
|
static int sleepms;
|
||||||
|
static int fd;
|
||||||
|
static int force;
|
||||||
|
static vlong offset0;
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(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);
|
threadexitsall(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pwriteblock(int fd, uchar *buf, int n, vlong off)
|
pwriteblock(uchar *buf, int n, vlong off)
|
||||||
{
|
{
|
||||||
int nr, m;
|
int nr, m;
|
||||||
|
|
||||||
for(nr = 0; nr < n; nr += m){
|
for(nr = 0; nr < n; nr += m){
|
||||||
m = n - nr;
|
m = n - nr;
|
||||||
m = pwrite(fd, &buf[nr], m, off+nr);
|
m = pwrite(fd, &buf[nr], m, offset0+off+nr);
|
||||||
if(m <= 0)
|
if(m <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -31,13 +32,13 @@ pwriteblock(int fd, uchar *buf, int n, vlong off)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
preadblock(int fd, uchar *buf, int n, vlong off)
|
preadblock(uchar *buf, int n, vlong off)
|
||||||
{
|
{
|
||||||
int nr, m;
|
int nr, m;
|
||||||
|
|
||||||
for(nr = 0; nr < n; nr += m){
|
for(nr = 0; nr < n; nr += m){
|
||||||
m = n - nr;
|
m = n - nr;
|
||||||
m = pread(fd, &buf[nr], m, off+nr);
|
m = pread(fd, &buf[nr], m, offset0+off+nr);
|
||||||
if(m <= 0){
|
if(m <= 0){
|
||||||
if(m == 0)
|
if(m == 0)
|
||||||
werrstr("early eof");
|
werrstr("early eof");
|
||||||
|
|
@ -48,26 +49,9 @@ preadblock(int fd, uchar *buf, int n, vlong off)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readblock(int fd, uchar *buf, int n)
|
loadheader(char *name, ArenaHead *head, Arena *arena, vlong off)
|
||||||
{
|
{
|
||||||
int nr, m;
|
if(preadblock(data, head->blocksize, off + head->size - head->blocksize) < 0){
|
||||||
|
|
||||||
for(nr = 0; nr < n; nr += m){
|
|
||||||
m = n - nr;
|
|
||||||
m = read(fd, &buf[nr], m);
|
|
||||||
if(m <= 0){
|
|
||||||
if(m == 0)
|
|
||||||
werrstr("early eof");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
loadheader(char *name, ArenaHead *head, Arena *arena, int fd, vlong off)
|
|
||||||
{
|
|
||||||
if(preadblock(fd, data, head->blocksize, off + head->size - head->blocksize) < 0){
|
|
||||||
fprint(2, "%s: reading arena tail: %r\n", name);
|
fprint(2, "%s: reading arena tail: %r\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +74,7 @@ loadheader(char *name, ArenaHead *head, Arena *arena, int fd, vlong off)
|
||||||
uchar zero[VtScoreSize];
|
uchar zero[VtScoreSize];
|
||||||
|
|
||||||
static int
|
static int
|
||||||
verify(int fd, Arena *arena, void *data, uchar *newscore)
|
verify(Arena *arena, void *data, uchar *newscore)
|
||||||
{
|
{
|
||||||
vlong e, bs, n, o;
|
vlong e, bs, n, o;
|
||||||
DigestState ds, ds1;
|
DigestState ds, ds1;
|
||||||
|
|
@ -105,7 +89,7 @@ verify(int fd, Arena *arena, void *data, uchar *newscore)
|
||||||
bs = arena->blocksize;
|
bs = arena->blocksize;
|
||||||
memset(&ds, 0, sizeof ds);
|
memset(&ds, 0, sizeof ds);
|
||||||
for(n = 0; n < e; n += bs){
|
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");
|
werrstr("read: %r");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +99,7 @@ verify(int fd, Arena *arena, void *data, uchar *newscore)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* last block */
|
/* last block */
|
||||||
if(preadblock(fd, data, arena->blocksize, o + e) < 0){
|
if(preadblock(data, arena->blocksize, o + e) < 0){
|
||||||
werrstr("read: %r");
|
werrstr("read: %r");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -123,8 +107,11 @@ verify(int fd, Arena *arena, void *data, uchar *newscore)
|
||||||
sha1(data, bs - VtScoreSize, nil, &ds);
|
sha1(data, bs - VtScoreSize, nil, &ds);
|
||||||
sha1(zero, VtScoreSize, score, &ds);
|
sha1(zero, VtScoreSize, score, &ds);
|
||||||
if(scorecmp(score, arena->score) != 0){
|
if(scorecmp(score, arena->score) != 0){
|
||||||
werrstr("score mismatch: %V != %V", score, arena->score);
|
if(!force){
|
||||||
return -1;
|
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 */
|
/* prepare new last block */
|
||||||
|
|
@ -154,7 +141,7 @@ resealarena(char *name, vlong len)
|
||||||
/*
|
/*
|
||||||
* read a little bit, which will include the header
|
* 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);
|
fprint(2, "%s: reading header: %r\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +156,7 @@ resealarena(char *name, vlong len)
|
||||||
if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
|
if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0)
|
||||||
fprint(2, "%s: warning: unexpected name %s\n", name, head.name);
|
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;
|
return;
|
||||||
|
|
||||||
if(!arena.diskstats.sealed){
|
if(!arena.diskstats.sealed){
|
||||||
|
|
@ -177,20 +164,19 @@ resealarena(char *name, vlong len)
|
||||||
return;
|
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);
|
fprint(2, "%s: failed to verify before reseal: %r\n", name);
|
||||||
return;
|
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);
|
fprint(2, "%s: writing new tail: %r\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scorecp(arena.score, newscore);
|
scorecp(arena.score, newscore);
|
||||||
fprint(2, "%s: resealed: %V\n", name, 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);
|
fprint(2, "%s: failed to verify after reseal!: %r\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -216,11 +202,11 @@ shouldcheck(char *name, char **s, int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
readap(int fd, ArenaPart *ap)
|
readap(ArenaPart *ap)
|
||||||
{
|
{
|
||||||
char *table;
|
char *table;
|
||||||
|
|
||||||
if(preadblock(fd, data, 8192, PartBlank) < 0)
|
if(preadblock(data, 8192, PartBlank) < 0)
|
||||||
sysfatal("read arena part header: %r");
|
sysfatal("read arena part header: %r");
|
||||||
if(unpackarenapart(ap, data) < 0)
|
if(unpackarenapart(ap, data) < 0)
|
||||||
sysfatal("corrupted arena part header: %r");
|
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->tabbase = (PartBlank+HeadSize+ap->blocksize-1)&~(ap->blocksize-1);
|
||||||
ap->tabsize = ap->arenabase - ap->tabbase;
|
ap->tabsize = ap->arenabase - ap->tabbase;
|
||||||
table = malloc(ap->tabsize+1);
|
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");
|
sysfatal("reading arena part directory: %r");
|
||||||
table[ap->tabsize] = 0;
|
table[ap->tabsize] = 0;
|
||||||
return table;
|
return table;
|
||||||
|
|
@ -242,6 +228,7 @@ threadmain(int argc, char *argv[])
|
||||||
char *p, *q, *table, *f[10], line[256];
|
char *p, *q, *table, *f[10], line[256];
|
||||||
vlong start, stop;
|
vlong start, stop;
|
||||||
ArenaPart ap;
|
ArenaPart ap;
|
||||||
|
Part *part;
|
||||||
|
|
||||||
ventifmtinstall();
|
ventifmtinstall();
|
||||||
blocksize = MaxIoSize;
|
blocksize = MaxIoSize;
|
||||||
|
|
@ -249,12 +236,12 @@ threadmain(int argc, char *argv[])
|
||||||
case 'b':
|
case 'b':
|
||||||
blocksize = unittoull(EARGF(usage()));
|
blocksize = unittoull(EARGF(usage()));
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
force = 1;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sleepms = atoi(EARGF(usage()));
|
sleepms = atoi(EARGF(usage()));
|
||||||
break;
|
break;
|
||||||
case 'v':
|
|
||||||
verbose++;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
|
|
@ -264,10 +251,12 @@ threadmain(int argc, char *argv[])
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
data = vtmalloc(blocksize);
|
data = vtmalloc(blocksize);
|
||||||
if((fd = open(argv[0], ORDWR)) < 0)
|
if((part = initpart(argv[0], ORDWR)) == nil)
|
||||||
sysfatal("open %s: %r", argv[0]);
|
sysfatal("open partition %s: %r", argv[0]);
|
||||||
|
fd = part->fd;
|
||||||
|
offset0 = part->offset;
|
||||||
|
|
||||||
table = readap(fd, &ap);
|
table = readap(&ap);
|
||||||
|
|
||||||
nline = atoi(table);
|
nline = atoi(table);
|
||||||
p = strchr(table, '\n');
|
p = strchr(table, '\n');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue