mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
sync with mit plan 9 version
This commit is contained in:
parent
33433b3fde
commit
27d2809820
28 changed files with 456 additions and 371 deletions
|
@ -30,7 +30,6 @@ threadmain(int argc, char **argv)
|
|||
VtReq *r;
|
||||
VtSrv *srv;
|
||||
char *address;
|
||||
Packet *p;
|
||||
|
||||
fmtinstall('V', vtscorefmt);
|
||||
fmtinstall('F', vtfcallfmt);
|
||||
|
@ -50,7 +49,7 @@ threadmain(int argc, char **argv)
|
|||
|
||||
srv = vtlisten(address);
|
||||
if(srv == nil)
|
||||
sysfatal("vtlisten %s: %s", address);
|
||||
sysfatal("vtlisten %s: %r", address);
|
||||
|
||||
while((r = vtgetreq(srv)) != nil){
|
||||
r->rx.msgtype = r->tx.msgtype+1;
|
||||
|
|
|
@ -13,3 +13,6 @@ BIN=$BIN/venti
|
|||
<$PLAN9/src/mkmany
|
||||
<$PLAN9/src/mkdirs
|
||||
|
||||
|
||||
extra:V: $O.devnull $O.mkroot $O.randtest $O.readlist $O.ro $O.root
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdinc.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <venti.h>
|
||||
#include <thread.h>
|
||||
|
||||
char *host;
|
||||
|
||||
|
@ -31,14 +32,15 @@ threadmain(int argc, char *argv[])
|
|||
if(argc != 5)
|
||||
usage();
|
||||
|
||||
ventifmtinstall();
|
||||
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], strlen(argv[2]), nil, root.score) < 0)
|
||||
if(vtparsescore(argv[2], nil, root.score) < 0)
|
||||
sysfatal("bad score '%s'", argv[2]);
|
||||
root.blocksize = atoi(argv[3]);
|
||||
if(vtparsescore(argv[4], strlen(argv[4]), nil, root.prev) < 0)
|
||||
if(vtparsescore(argv[4], nil, root.prev) < 0)
|
||||
sysfatal("bad score '%s'", argv[4]);
|
||||
vtrootpack(&root, buf);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ wr(char *buf, char *buf2)
|
|||
uchar score[VtScoreSize], score2[VtScoreSize];
|
||||
DigestState ds;
|
||||
|
||||
USED(buf2);
|
||||
memset(&ds, 0, sizeof ds);
|
||||
if(doublecheck)
|
||||
sha1((uchar*)buf, blocksize, score, &ds);
|
||||
|
|
|
@ -27,7 +27,7 @@ bloominit(Bloom *b, vlong vsize, u8int *data)
|
|||
return -1;
|
||||
|
||||
fprint(2, "bloom size %lud nhash %d\n", b->size, b->nhash);
|
||||
b->mask = b->size-1;
|
||||
b->bitmask = (b->size<<3) - 1;
|
||||
b->data = data;
|
||||
return 0;
|
||||
}
|
||||
|
@ -47,11 +47,17 @@ readbloom(Part *p)
|
|||
b = vtmallocz(sizeof *b);
|
||||
if(readpart(p, 0, buf, sizeof buf) < 0)
|
||||
return nil;
|
||||
/*
|
||||
* pass buf as b->data so that bloominit
|
||||
* can parse header. won't be used for
|
||||
* accessing bits (cleared below).
|
||||
*/
|
||||
if(bloominit(b, 0, buf) < 0){
|
||||
vtfree(b);
|
||||
return nil;
|
||||
}
|
||||
b->part = p;
|
||||
b->data = nil;
|
||||
return b;
|
||||
}
|
||||
|
||||
|
@ -61,7 +67,6 @@ resetbloom(Bloom *b)
|
|||
uchar *data;
|
||||
|
||||
data = vtmallocz(b->size);
|
||||
fprint(2, "bloom data %lud\n", b->size);
|
||||
b->data = data;
|
||||
if(b->size == MaxBloomSize) /* 2^32 overflows ulong */
|
||||
addstat(StatBloomBits, b->size*8-1);
|
||||
|
@ -145,7 +150,7 @@ _markbloomfilter(Bloom *b, u8int *score)
|
|||
tab = (u32int*)b->data;
|
||||
for(i=0; i<b->nhash; i++){
|
||||
x = h[i];
|
||||
y = &tab[(x&b->mask)>>5];
|
||||
y = &tab[(x&b->bitmask)>>5];
|
||||
z = 1<<(x&31);
|
||||
if(!(*y&z)){
|
||||
nnew++;
|
||||
|
@ -169,7 +174,7 @@ _inbloomfilter(Bloom *b, u8int *score)
|
|||
tab = (u32int*)b->data;
|
||||
for(i=0; i<b->nhash; i++){
|
||||
x = h[i];
|
||||
if(!(tab[(x&b->mask)>>5] & (1<<(x&31))))
|
||||
if(!(tab[(x&b->bitmask)>>5] & (1<<(x&31))))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -112,7 +112,7 @@ threadmain(int argc, char *argv[])
|
|||
argc--;
|
||||
argv++;
|
||||
|
||||
part = initpart(file, ORDWR|ODIRECT);
|
||||
part = initpart(file, (fix ? ORDWR : OREAD)|ODIRECT);
|
||||
if(part == nil)
|
||||
sysfatal("can't open partition %s: %r", file);
|
||||
|
||||
|
|
|
@ -116,8 +116,7 @@ u64int found = 0;
|
|||
if(b == nil || z == nil || ies == nil){
|
||||
werrstr("allocating: %r");
|
||||
ok = -1;
|
||||
goto breakout;
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
ok = 0;
|
||||
next = 0;
|
||||
|
@ -138,7 +137,7 @@ u64int found = 0;
|
|||
}
|
||||
if(ok < 0)
|
||||
werrstr("%d spurious entries, %d missing, %d wrong", extra, missing, wrong);
|
||||
goto breakout;
|
||||
goto out;
|
||||
}
|
||||
bok = checkbucket(ix, next, &zib);
|
||||
if(bok < 0)
|
||||
|
@ -150,14 +149,14 @@ u64int found = 0;
|
|||
break;
|
||||
werrstr("internal error: bucket out of range");
|
||||
ok = -1;
|
||||
goto breakout;
|
||||
goto out;
|
||||
}
|
||||
bok = checkbucket(ix, buck, &ib);
|
||||
if(bok < 0)
|
||||
ok = -1;
|
||||
next = buck + 1;
|
||||
}
|
||||
breakout:
|
||||
out:
|
||||
freeiestream(ies);
|
||||
freezblock(z);
|
||||
freezblock(b);
|
||||
|
|
|
@ -51,21 +51,64 @@ readblock(int fd, uchar *buf, int n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
printheader(char *name, ArenaHead *head, int fd)
|
||||
{
|
||||
Arena arena;
|
||||
vlong baseoff, lo, hi, off;
|
||||
int clumpmax;
|
||||
|
||||
off = seek(fd, 0, 1);
|
||||
seek(fd, off + head->size - head->blocksize, 0);
|
||||
if(readblock(fd, data, head->blocksize) < 0){
|
||||
fprint(2, "%s: reading arena tail: %r\n", name);
|
||||
return -1;
|
||||
}
|
||||
seek(fd, off, 0);
|
||||
|
||||
memset(&arena, 0, sizeof arena);
|
||||
if(unpackarena(&arena, data) < 0){
|
||||
fprint(2, "%s: unpack arena tail: %r\n", name);
|
||||
return -1;
|
||||
}
|
||||
arena.blocksize = head->blocksize;
|
||||
arena.base = off + head->blocksize;
|
||||
arena.clumpmax = arena.blocksize / ClumpInfoSize;
|
||||
arena.size = head->size - 2*head->blocksize;
|
||||
|
||||
fprint(2, "%s: base=%llx size=%llx blocksize=%x\n", name, off, head->size, head->blocksize);
|
||||
|
||||
baseoff = head->blocksize;
|
||||
fprint(2, "\t%llx-%llx: head\n", (vlong)0, baseoff);
|
||||
lo = baseoff;
|
||||
hi = baseoff + arena.diskstats.used;
|
||||
fprint(2, "\t%llx-%llx: data (%llx)\n", lo, hi, hi - lo);
|
||||
hi = head->size - head->blocksize;
|
||||
clumpmax = head->blocksize / ClumpInfoSize;
|
||||
if(clumpmax > 0)
|
||||
lo = hi - (u64int)arena.diskstats.clumps/clumpmax * head->blocksize;
|
||||
else
|
||||
lo = hi;
|
||||
fprint(2, "\t%llx-%llx: clumps (%llx)\n", lo, hi, hi - lo);
|
||||
fprint(2, "\t%llx-%llx: tail\n", hi, hi + head->blocksize);
|
||||
|
||||
fprint(2, "arena:\n");
|
||||
printarena(2, &arena);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cmparena(char *name, vlong len)
|
||||
{
|
||||
Arena arena;
|
||||
ArenaHead head;
|
||||
DigestState s;
|
||||
u64int n, e;
|
||||
u32int bs;
|
||||
u8int score[VtScoreSize];
|
||||
int i, j;
|
||||
char buf[20];
|
||||
|
||||
fprint(2, "cmp %s\n", name);
|
||||
|
||||
memset(&arena, 0, sizeof arena);
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
/*
|
||||
|
@ -104,6 +147,9 @@ cmparena(char *name, vlong len)
|
|||
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
|
||||
|
|
|
@ -34,7 +34,7 @@ fmtmagic(char *s, u32int m)
|
|||
for(i=0; i<nelem(magics); i++)
|
||||
if(magics[i].m == m)
|
||||
return magics[i].s;
|
||||
sprint(s, "0x%08ux", m);
|
||||
sprint(s, "%#08ux", m);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ unpackarenapart(ArenaPart *ap, u8int *buf)
|
|||
|
||||
m = U32GET(p);
|
||||
if(m != ArenaPartMagic){
|
||||
seterr(ECorrupt, "arena set has wrong magic number: %s expected ArenaPartMagic (%lux)", fmtmagic(fbuf, m), ArenaPartMagic);
|
||||
seterr(ECorrupt, "arena set has wrong magic number: %s expected ArenaPartMagic (%#lux)", fmtmagic(fbuf, m), ArenaPartMagic);
|
||||
return -1;
|
||||
}
|
||||
p += U32Size;
|
||||
|
@ -112,7 +112,7 @@ unpackarena(Arena *arena, u8int *buf)
|
|||
|
||||
m = U32GET(p);
|
||||
if(m != ArenaMagic){
|
||||
seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaMagic (%lux)", fmtmagic(fbuf, m), ArenaMagic);
|
||||
seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaMagic (%#lux)", fmtmagic(fbuf, m), ArenaMagic);
|
||||
return -1;
|
||||
}
|
||||
p += U32Size;
|
||||
|
@ -276,10 +276,15 @@ unpackarenahead(ArenaHead *head, u8int *buf)
|
|||
u8int *p;
|
||||
u32int m;
|
||||
int sz;
|
||||
char fbuf[20];
|
||||
|
||||
p = buf;
|
||||
|
||||
m = U32GET(p);
|
||||
if(m != ArenaHeadMagic){
|
||||
seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaHeadMagic (%#lux)", fmtmagic(fbuf, m), ArenaHeadMagic);
|
||||
return -1;
|
||||
}
|
||||
/* XXX check magic! */
|
||||
|
||||
p += U32Size;
|
||||
|
@ -497,7 +502,7 @@ unpackisect(ISect *is, u8int *buf)
|
|||
|
||||
m = U32GET(p);
|
||||
if(m != ISectMagic){
|
||||
seterr(ECorrupt, "index section has wrong magic number: %s expected ISectMagic (%lux)",
|
||||
seterr(ECorrupt, "index section has wrong magic number: %s expected ISectMagic (%#lux)",
|
||||
fmtmagic(fbuf, m), ISectMagic);
|
||||
return -1;
|
||||
}
|
||||
|
@ -665,7 +670,7 @@ unpackbloomhead(Bloom *b, u8int *buf)
|
|||
|
||||
m = U32GET(p);
|
||||
if(m != BloomMagic){
|
||||
seterr(ECorrupt, "bloom filter has wrong magic number: %s expected BloomMagic (%lux)", fmtmagic(fbuf, m), (ulong)BloomMagic);
|
||||
seterr(ECorrupt, "bloom filter has wrong magic number: %s expected BloomMagic (%#lux)", fmtmagic(fbuf, m), (ulong)BloomMagic);
|
||||
return -1;
|
||||
}
|
||||
p += U32Size;
|
||||
|
@ -682,6 +687,10 @@ unpackbloomhead(Bloom *b, u8int *buf)
|
|||
|
||||
b->size = U32GET(p);
|
||||
p += U32Size;
|
||||
if(b->size < BloomHeadSize || b->size > MaxBloomSize || (b->size&(b->size-1))){
|
||||
seterr(ECorrupt, "bloom filter has invalid size %#lux", b->size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(buf + BloomHeadSize != p)
|
||||
sysfatal("unpackarena unpacked wrong amount");
|
||||
|
|
|
@ -696,7 +696,7 @@ struct Bloom
|
|||
QLock mod; /* one marker at a time, protects nb */
|
||||
int nhash;
|
||||
ulong size; /* bytes in tab */
|
||||
ulong mask; /* to produce index */
|
||||
ulong bitmask; /* to produce bit index */
|
||||
u8int *data;
|
||||
Part *part;
|
||||
Channel *writechan;
|
||||
|
|
|
@ -169,10 +169,23 @@ raproc(void *v)
|
|||
b = _getdblock(ra.part, ra.addr, OREAD, 2);
|
||||
putdblock(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We do readahead a whole arena at a time now,
|
||||
* so dreadahead is a no-op. The original implementation
|
||||
* is in unused_dreadahead below.
|
||||
*/
|
||||
void
|
||||
dreadahead(Part *part, u64int addr, int miss)
|
||||
{
|
||||
USED(part);
|
||||
USED(addr);
|
||||
USED(miss);
|
||||
}
|
||||
|
||||
void
|
||||
unused_dreadahead(Part *part, u64int addr, int miss)
|
||||
{
|
||||
Ra ra;
|
||||
static struct {
|
||||
|
@ -185,7 +198,6 @@ dreadahead(Part *part, u64int addr, int miss)
|
|||
int dir;
|
||||
} lastra;
|
||||
|
||||
return;
|
||||
if(miss){
|
||||
if(lastmiss.part==part && lastmiss.addr==addr-dcache.size){
|
||||
XRa:
|
||||
|
|
|
@ -976,7 +976,6 @@ ltreewalk(int *p, uchar *score)
|
|||
else
|
||||
p = &cibuf[*p].left;
|
||||
}
|
||||
return nil; /* stupid 8c */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1024,7 +1023,6 @@ haveclump(uchar *score)
|
|||
else
|
||||
p = cibuf[p].left;
|
||||
}
|
||||
return 0; /* stupid 8c */
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -51,6 +51,13 @@ void freezblock(ZBlock *b);
|
|||
DBlock *_getdblock(Part *part, u64int addr, int mode, int load);
|
||||
DBlock *getdblock(Part *part, u64int addr, int mode);
|
||||
u32int hashbits(u8int *score, int nbits);
|
||||
char *hargstr(HConnect*, char*, char*);
|
||||
vlong hargint(HConnect*, char*, vlong);
|
||||
int hdebug(HConnect*);
|
||||
int hdisk(HConnect*);
|
||||
int hnotfound(HConnect*);
|
||||
int hsethtml(HConnect*);
|
||||
int hsettext(HConnect*);
|
||||
int httpdinit(char *address, char *webroot);
|
||||
int iaddrcmp(IAddr *ia1, IAddr *ia2);
|
||||
IEntry* icachedirty(u32int, u32int, u64int);
|
||||
|
@ -89,6 +96,7 @@ DBlock *loadibucket(Index *index, u8int *score, ISect **is, u32int *buck, IBucke
|
|||
int loadientry(Index *index, u8int *score, int type, IEntry *ie);
|
||||
void logerr(int severity, char *fmt, ...);
|
||||
Lump *lookuplump(u8int *score, int type);
|
||||
int _lookupscore(u8int *score, int type, IAddr *ia, int *rac);
|
||||
int lookupscore(u8int *score, int type, IAddr *ia, int *rac);
|
||||
int maparenas(AMap *am, Arena **arenas, int n, char *what);
|
||||
void markbloomfilter(Bloom*, u8int*);
|
||||
|
|
|
@ -111,7 +111,7 @@ scalept(int val, int valmin, int valmax, int ptmin, int ptmax)
|
|||
Memimage*
|
||||
statgraph(Graph *g)
|
||||
{
|
||||
int i, lastlo, nbin, x, lo, hi, min, max, first;
|
||||
int i, nbin, x, lo, hi, min, max, first;
|
||||
Memimage *m;
|
||||
Rectangle r;
|
||||
Statbin *b, bin[2000]; /* 32 kB, but whack is worse */
|
||||
|
@ -178,7 +178,6 @@ statgraph(Graph *g)
|
|||
drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min);
|
||||
|
||||
/* actual data */
|
||||
lastlo = -1;
|
||||
for(i=0; i<nbin; i++){
|
||||
b = &bin[i];
|
||||
if(b->nsamp == 0)
|
||||
|
@ -187,16 +186,8 @@ statgraph(Graph *g)
|
|||
hi = scalept(b->max, min, max, r.max.y, r.min.y);
|
||||
x = r.min.x+i;
|
||||
hi-=2;
|
||||
if(0)
|
||||
if(lastlo != -1){
|
||||
if(lastlo < lo)
|
||||
memimagedraw(m, Rect(x-1, lastlo, x, lo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S);
|
||||
else if(lastlo > lo)
|
||||
memimagedraw(m, Rect(x-1, lo, x, lastlo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S);
|
||||
}
|
||||
memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S);
|
||||
memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill%nelem(lofill)], ZP, memopaque, ZP, S);
|
||||
lastlo = lo;
|
||||
}
|
||||
|
||||
if(bin[nbin-1].nsamp)
|
||||
|
|
|
@ -36,7 +36,6 @@ static int hicachekick(HConnect *c);
|
|||
static int hdcachekick(HConnect *c);
|
||||
static int hicacheflush(HConnect *c);
|
||||
static int hdcacheflush(HConnect *c);
|
||||
static int notfound(HConnect *c);
|
||||
static int httpdobj(char *name, int (*f)(HConnect*));
|
||||
static int xgraph(HConnect *c);
|
||||
static int xset(HConnect *c);
|
||||
|
@ -61,15 +60,15 @@ httpdinit(char *address, char *dir)
|
|||
httpdobj("/flushdcache", hdcacheflush);
|
||||
httpdobj("/kickicache", hicachekick);
|
||||
httpdobj("/kickdcache", hdcachekick);
|
||||
httpdobj("/graph/", xgraph);
|
||||
httpdobj("/graph", xgraph);
|
||||
httpdobj("/set", xset);
|
||||
httpdobj("/set/", xset);
|
||||
httpdobj("/log", xlog);
|
||||
httpdobj("/log/", xlog);
|
||||
httpdobj("/empty", hempty);
|
||||
httpdobj("/emptyicache", hicacheempty);
|
||||
httpdobj("/emptylumpcache", hlcacheempty);
|
||||
httpdobj("/emptydcache", hdcacheempty);
|
||||
httpdobj("/disk", hdisk);
|
||||
httpdobj("/debug", hdebug);
|
||||
|
||||
if(vtproc(listenproc, address) < 0)
|
||||
return -1;
|
||||
|
@ -168,6 +167,11 @@ httpproc(void *v)
|
|||
*/
|
||||
if(hparsereq(c, 0) < 0)
|
||||
break;
|
||||
|
||||
if(c->req.search)
|
||||
c->req.searchpairs = hparsequery(c, c->req.search);
|
||||
else
|
||||
c->req.searchpairs = nil;
|
||||
|
||||
for(i = 0; i < MaxObjs && objs[i].name[0]; i++){
|
||||
n = strlen(objs[i].name);
|
||||
|
@ -179,6 +183,7 @@ httpproc(void *v)
|
|||
}
|
||||
ok = fromwebdir(c);
|
||||
found:
|
||||
hflush(&c->hout);
|
||||
if(c->head.closeit)
|
||||
ok = -1;
|
||||
hreqcleanup(c);
|
||||
|
@ -191,6 +196,27 @@ httpproc(void *v)
|
|||
free(c);
|
||||
}
|
||||
|
||||
char*
|
||||
hargstr(HConnect *c, char *name, char *def)
|
||||
{
|
||||
HSPairs *p;
|
||||
|
||||
for(p=c->req.searchpairs; p; p=p->next)
|
||||
if(strcmp(p->s, name) == 0)
|
||||
return p->t;
|
||||
return def;
|
||||
}
|
||||
|
||||
vlong
|
||||
hargint(HConnect *c, char *name, vlong def)
|
||||
{
|
||||
char *a;
|
||||
|
||||
if((a = hargstr(c, name, nil)) == nil)
|
||||
return def;
|
||||
return atoll(a);
|
||||
}
|
||||
|
||||
static int
|
||||
percent(ulong v, ulong total)
|
||||
{
|
||||
|
@ -217,8 +243,8 @@ preq(HConnect *c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
preqtype(HConnect *c, char *type)
|
||||
int
|
||||
hsettype(HConnect *c, char *type)
|
||||
{
|
||||
Hio *hout;
|
||||
int r;
|
||||
|
@ -243,10 +269,16 @@ preqtype(HConnect *c, char *type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
preqtext(HConnect *c)
|
||||
int
|
||||
hsethtml(HConnect *c)
|
||||
{
|
||||
return preqtype(c, "text/plain");
|
||||
return hsettype(c, "text/html; charset=utf-8");
|
||||
}
|
||||
|
||||
int
|
||||
hsettext(HConnect *c)
|
||||
{
|
||||
return hsettype(c, "text/plain; charset=utf-8");
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -274,8 +306,8 @@ herror(HConnect *c)
|
|||
return hflush(hout);
|
||||
}
|
||||
|
||||
static int
|
||||
notfound(HConnect *c)
|
||||
int
|
||||
hnotfound(HConnect *c)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -305,16 +337,16 @@ fromwebdir(HConnect *c)
|
|||
Dir *d;
|
||||
|
||||
if(webroot == nil || strstr(c->req.uri, ".."))
|
||||
return notfound(c);
|
||||
return hnotfound(c);
|
||||
snprint(buf, sizeof buf-20, "%s/%s", webroot, c->req.uri+1);
|
||||
defaulted = 0;
|
||||
reopen:
|
||||
if((fd = open(buf, OREAD)) < 0)
|
||||
return notfound(c);
|
||||
return hnotfound(c);
|
||||
d = dirfstat(fd);
|
||||
if(d == nil){
|
||||
close(fd);
|
||||
return notfound(c);
|
||||
return hnotfound(c);
|
||||
}
|
||||
if(d->mode&DMDIR){
|
||||
if(!defaulted){
|
||||
|
@ -325,7 +357,7 @@ reopen:
|
|||
goto reopen;
|
||||
}
|
||||
free(d);
|
||||
return notfound(c);
|
||||
return hnotfound(c);
|
||||
}
|
||||
free(d);
|
||||
p = buf+strlen(buf);
|
||||
|
@ -337,7 +369,7 @@ reopen:
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(preqtype(c, type) < 0){
|
||||
if(hsettype(c, type) < 0){
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
@ -371,55 +403,42 @@ static struct
|
|||
0
|
||||
};
|
||||
|
||||
static int
|
||||
xsetlist(HConnect *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(preqtype(c, "text/plain") < 0)
|
||||
return -1;
|
||||
for(i=0; namedints[i].name; i++)
|
||||
print("%s = %d\n", namedints[i].name, *namedints[i].p);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
xset(HConnect *c)
|
||||
{
|
||||
int i, nf, r;
|
||||
char *f[10], *s;
|
||||
int i, old;
|
||||
char *name, *value;
|
||||
|
||||
if(strcmp(c->req.uri, "/set") == 0 || strcmp(c->req.uri, "/set/") == 0)
|
||||
return xsetlist(c);
|
||||
if(hsettext(c) < 0)
|
||||
return -1;
|
||||
|
||||
s = estrdup(c->req.uri);
|
||||
nf = getfields(s+strlen("/set/"), f, nelem(f), 1, "/");
|
||||
|
||||
if(nf < 1){
|
||||
r = preqtext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
if((name = hargstr(c, "name", nil)) == nil || name[0] == 0){
|
||||
for(i=0; namedints[i].name; i++)
|
||||
hprint(&c->hout, "%s = %d\n", namedints[i].name, *namedints[i].p);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
}
|
||||
for(i=0; namedints[i].name; i++){
|
||||
if(strcmp(f[0], namedints[i].name) == 0){
|
||||
if(nf >= 2)
|
||||
*namedints[i].p = atoi(f[1]);
|
||||
r = preqtext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hprint(&c->hout, "%s = %d\n", f[0], *namedints[i].p);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i=0; namedints[i].name; i++)
|
||||
if(strcmp(name, namedints[i].name) == 0)
|
||||
break;
|
||||
if(!namedints[i].name){
|
||||
hprint(&c->hout, "%s not found\n", name);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
}
|
||||
return notfound(c);
|
||||
|
||||
if((value = hargstr(c, "value", nil)) == nil || value[0] == 0){
|
||||
hprint(&c->hout, "%s = %d\n", namedints[i].name, *namedints[i].p);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
old = *namedints[i].p;
|
||||
*namedints[i].p = atoll(value);
|
||||
hprint(&c->hout, "%s = %d (was %d)\n", name, *namedints[i].p, old);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -428,7 +447,7 @@ estats(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -503,7 +522,7 @@ sindex(HConnect *c)
|
|||
vlong clumps, cclumps, uncsize, used, size;
|
||||
int i, r, active;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -567,7 +586,7 @@ hempty(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -586,7 +605,7 @@ hlcacheempty(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -603,7 +622,7 @@ hicacheempty(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -620,7 +639,7 @@ hdcacheempty(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -636,7 +655,7 @@ hicachekick(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -653,7 +672,7 @@ hdcachekick(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -669,7 +688,7 @@ hicacheflush(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -686,7 +705,7 @@ hdcacheflush(HConnect *c)
|
|||
Hio *hout;
|
||||
int r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -704,7 +723,7 @@ dindex(HConnect *c)
|
|||
Index *ix;
|
||||
int i, r;
|
||||
|
||||
r = preqtext(c);
|
||||
r = hsettext(c);
|
||||
if(r < 0)
|
||||
return r;
|
||||
hout = &c->hout;
|
||||
|
@ -771,6 +790,23 @@ pctdiffgraph(Stats *s, Stats *t, void *va)
|
|||
return percent(t->n[a->index]-s->n[a->index], t->n[a->index2]-s->n[a->index2]);
|
||||
}
|
||||
|
||||
static long
|
||||
div(long a, long b)
|
||||
{
|
||||
if(b == 0)
|
||||
b++;
|
||||
return a/b;
|
||||
}
|
||||
|
||||
static long
|
||||
divdiffgraph(Stats *s, Stats *t, void *va)
|
||||
{
|
||||
Arg *a;
|
||||
|
||||
a = va;
|
||||
return div(t->n[a->index] - s->n[a->index], t->n[a->index2] - s->n[a->index2]);
|
||||
}
|
||||
|
||||
static long
|
||||
netbw(Stats *s)
|
||||
{
|
||||
|
@ -928,79 +964,59 @@ dotextbin(Hio *io, Graph *g)
|
|||
static int
|
||||
xgraph(HConnect *c)
|
||||
{
|
||||
char *f[20], *s;
|
||||
char *name;
|
||||
Hio *hout;
|
||||
Memimage *m;
|
||||
int i, nf, dotext;
|
||||
int dotext;
|
||||
Graph g;
|
||||
Arg arg;
|
||||
char *graph, *a;
|
||||
|
||||
s = estrdup(c->req.uri);
|
||||
if(0) fprint(2, "graph %s\n" ,s);
|
||||
memset(&g, 0, sizeof g);
|
||||
nf = getfields(s+strlen("/graph/"), f, nelem(f), 1, "/");
|
||||
if(nf < 1){
|
||||
werrstr("bad syntax -- not enough fields");
|
||||
name = hargstr(c, "arg", "");
|
||||
if((arg.index = findname(name)) == -1 && strcmp(name, "*") != 0){
|
||||
werrstr("unknown name %s", name);
|
||||
goto error;
|
||||
}
|
||||
if((arg.index = findname(f[0])) == -1 && strcmp(f[0], "*") != 0){
|
||||
werrstr("unknown name %s", f[0]);
|
||||
a = hargstr(c, "arg2", "");
|
||||
if(a[0] && (arg.index2 = findname(a)) == -1){
|
||||
werrstr("unknown name %s", a);
|
||||
goto error;
|
||||
}
|
||||
|
||||
g.arg = &arg;
|
||||
g.t0 = -120;
|
||||
g.t1 = 0;
|
||||
g.min = -1;
|
||||
g.max = -1;
|
||||
g.fn = rawgraph;
|
||||
g.wid = -1;
|
||||
g.ht = -1;
|
||||
dotext = 0;
|
||||
g.fill = -1;
|
||||
for(i=1; i<nf; i++){
|
||||
if(strncmp(f[i], "t0=", 3) == 0)
|
||||
g.t0 = atoi(f[i]+3);
|
||||
else if(strncmp(f[i], "t1=", 3) == 0)
|
||||
g.t1 = atoi(f[i]+3);
|
||||
else if(strncmp(f[i], "min=", 4) == 0)
|
||||
g.min = atoi(f[i]+4);
|
||||
else if(strncmp(f[i], "max=", 4) == 0)
|
||||
g.max = atoi(f[i]+4);
|
||||
else if(strncmp(f[i], "pct=", 4) == 0){
|
||||
if((arg.index2 = findname(f[i]+4)) == -1){
|
||||
werrstr("unknown name %s", f[i]+4);
|
||||
goto error;
|
||||
}
|
||||
g.fn = pctgraph;
|
||||
g.min = 0;
|
||||
g.max = 100;
|
||||
}else if(strncmp(f[i], "pctdiff=", 8) == 0){
|
||||
if((arg.index2 = findname(f[i]+8)) == -1){
|
||||
werrstr("unknown name %s", f[i]+8);
|
||||
goto error;
|
||||
}
|
||||
g.fn = pctdiffgraph;
|
||||
g.min = 0;
|
||||
g.max = 100;
|
||||
}else if(strcmp(f[i], "diff") == 0)
|
||||
g.fn = diffgraph;
|
||||
else if(strcmp(f[i], "text") == 0)
|
||||
dotext = 1;
|
||||
else if(strncmp(f[i], "wid=", 4) == 0)
|
||||
g.wid = atoi(f[i]+4);
|
||||
else if(strncmp(f[i], "ht=", 3) == 0)
|
||||
g.ht = atoi(f[i]+3);
|
||||
else if(strncmp(f[i], "fill=", 5) == 0)
|
||||
g.fill = atoi(f[i]+5);
|
||||
else if(strcmp(f[i], "diskbw") == 0)
|
||||
g.fn = diskgraph;
|
||||
else if(strcmp(f[i], "iobw") == 0)
|
||||
g.fn = iograph;
|
||||
else if(strcmp(f[i], "netbw") == 0)
|
||||
g.fn = netgraph;
|
||||
g.t0 = hargint(c, "t0", -120);
|
||||
g.t1 = hargint(c, "t1", 0);
|
||||
g.min = hargint(c, "min", -1);
|
||||
g.max = hargint(c, "max", -1);
|
||||
g.wid = hargint(c, "wid", -1);
|
||||
g.ht = hargint(c, "ht", -1);
|
||||
dotext = hargstr(c, "text", "")[0] != 0;
|
||||
g.fill = hargint(c, "fill", -1);
|
||||
|
||||
graph = hargstr(c, "graph", "raw");
|
||||
if(strcmp(graph, "raw") == 0)
|
||||
g.fn = rawgraph;
|
||||
else if(strcmp(graph, "diskbw") == 0)
|
||||
g.fn = diskgraph;
|
||||
else if(strcmp(graph, "iobw") == 0)
|
||||
g.fn = iograph;
|
||||
else if(strcmp(graph, "netbw") == 0)
|
||||
g.fn = netgraph;
|
||||
else if(strcmp(graph, "diff") == 0)
|
||||
g.fn = diffgraph;
|
||||
else if(strcmp(graph, "pct") == 0)
|
||||
g.fn = pctgraph;
|
||||
else if(strcmp(graph, "pctdiff") == 0)
|
||||
g.fn = pctdiffgraph;
|
||||
else if(strcmp(graph, "divdiff") == 0)
|
||||
g.fn = divdiffgraph;
|
||||
else{
|
||||
werrstr("unknown graph %s", graph);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(dotext){
|
||||
preqtype(c, "text/plain");
|
||||
hsettype(c, "text/plain");
|
||||
dotextbin(&c->hout, &g);
|
||||
hflush(&c->hout);
|
||||
return 0;
|
||||
|
@ -1010,7 +1026,7 @@ if(0) fprint(2, "graph %s\n" ,s);
|
|||
if(m == nil)
|
||||
goto error;
|
||||
|
||||
if(preqtype(c, "image/png") < 0)
|
||||
if(hsettype(c, "image/png") < 0)
|
||||
return -1;
|
||||
hout = &c->hout;
|
||||
writepng(hout, m);
|
||||
|
@ -1018,18 +1034,16 @@ if(0) fprint(2, "graph %s\n" ,s);
|
|||
freememimage(m);
|
||||
qunlock(&memdrawlock);
|
||||
hflush(hout);
|
||||
free(s);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(s);
|
||||
return herror(c);
|
||||
}
|
||||
|
||||
static int
|
||||
xloglist(HConnect *c)
|
||||
{
|
||||
if(preqtype(c, "text/html") < 0)
|
||||
if(hsettype(c, "text/html") < 0)
|
||||
return -1;
|
||||
vtloghlist(&c->hout);
|
||||
hflush(&c->hout);
|
||||
|
@ -1042,15 +1056,13 @@ xlog(HConnect *c)
|
|||
char *name;
|
||||
VtLog *l;
|
||||
|
||||
if(strcmp(c->req.uri, "/log") == 0 || strcmp(c->req.uri, "/log/") == 0)
|
||||
name = hargstr(c, "log", "");
|
||||
if(!name[0])
|
||||
return xloglist(c);
|
||||
if(strncmp(c->req.uri, "/log/", 5) != 0)
|
||||
return notfound(c);
|
||||
name = c->req.uri + strlen("/log/");
|
||||
l = vtlogopen(name, 0);
|
||||
if(l == nil)
|
||||
return notfound(c);
|
||||
if(preqtype(c, "text/html") < 0){
|
||||
return hnotfound(c);
|
||||
if(hsettype(c, "text/html") < 0){
|
||||
vtlogclose(l);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1063,7 +1075,7 @@ xlog(HConnect *c)
|
|||
static int
|
||||
xindex(HConnect *c)
|
||||
{
|
||||
if(preqtype(c, "text/xml") < 0)
|
||||
if(hsettype(c, "text/xml") < 0)
|
||||
return -1;
|
||||
xmlindex(&c->hout, mainindex, "index", 0);
|
||||
hflush(&c->hout);
|
||||
|
@ -1158,7 +1170,7 @@ vtloghlist(Hio *h)
|
|||
p = vtlognames(&n);
|
||||
qsort(p, n, sizeof(p[0]), strpcmp);
|
||||
for(i=0; i<n; i++)
|
||||
hprint(h, "<a href=\"/log/%s\">%s</a><br>\n", p[i], p[i]);
|
||||
hprint(h, "<a href=\"/log?log=%s\">%s</a><br>\n", p[i], p[i]);
|
||||
vtfree(p);
|
||||
hprint(h, "</body></html>\n");
|
||||
}
|
||||
|
|
|
@ -86,6 +86,42 @@ fprint(2, "seed index cache with arena @%llud, (map %llud), %d clumps\n", arena-
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
_lookupscore(u8int *score, int type, IAddr *ia, int *rac)
|
||||
{
|
||||
u32int h;
|
||||
IEntry *ie, *last;
|
||||
|
||||
qlock(&icache.lock);
|
||||
h = hashbits(score, icache.bits);
|
||||
last = nil;
|
||||
for(ie = icache.heads[h]; ie != nil; ie = ie->next){
|
||||
if((ie->ia.type == type || type == -1) && scorecmp(ie->score, score)==0){
|
||||
if(last != nil)
|
||||
last->next = ie->next;
|
||||
else
|
||||
icache.heads[h] = ie->next;
|
||||
addstat(StatIcacheHit, 1);
|
||||
if(rac)
|
||||
ie->rac = 1;
|
||||
trace(TraceLump, "lookupscore incache");
|
||||
ie->next = icache.heads[h];
|
||||
icache.heads[h] = ie;
|
||||
|
||||
*ia = ie->ia;
|
||||
if(rac)
|
||||
*rac = ie->rac;
|
||||
qunlock(&icache.lock);
|
||||
return 0;
|
||||
}
|
||||
last = ie;
|
||||
}
|
||||
addstat(StatIcacheMiss, 1);
|
||||
qunlock(&icache.lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ZZZ need to think about evicting the correct IEntry,
|
||||
and writing back the wtime.
|
||||
|
@ -97,88 +133,72 @@ and writing back the wtime.
|
|||
int
|
||||
lookupscore(u8int *score, int type, IAddr *ia, int *rac)
|
||||
{
|
||||
IEntry d, *ie, *last;
|
||||
IEntry d, *ie;
|
||||
u32int h;
|
||||
u64int aa;
|
||||
Arena *load;
|
||||
int i;
|
||||
int i, ret;
|
||||
uint ms;
|
||||
|
||||
load = nil;
|
||||
aa = 0;
|
||||
ms = msec();
|
||||
|
||||
trace(TraceLump, "lookupscore %V.%d", score, type);
|
||||
|
||||
qlock(&icache.lock);
|
||||
h = hashbits(score, icache.bits);
|
||||
last = nil;
|
||||
for(ie = icache.heads[h]; ie != nil; ie = ie->next){
|
||||
if(ie->ia.type == type && scorecmp(ie->score, score)==0){
|
||||
if(last != nil)
|
||||
last->next = ie->next;
|
||||
else
|
||||
icache.heads[h] = ie->next;
|
||||
addstat(StatIcacheHit, 1);
|
||||
ie->rac = 1;
|
||||
trace(TraceLump, "lookupscore incache");
|
||||
goto found;
|
||||
ret = 0;
|
||||
if(_lookupscore(score, type, ia, rac) < 0){
|
||||
if(loadientry(mainindex, score, type, &d) < 0){
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
last = ie;
|
||||
}
|
||||
addstat(StatIcacheMiss, 1);
|
||||
qunlock(&icache.lock);
|
||||
|
||||
if(loadientry(mainindex, score, type, &d) < 0){
|
||||
ms = msec() - ms;
|
||||
addstat2(StatIcacheRead, 1, StatIcacheReadTime, ms);
|
||||
return -1;
|
||||
}
|
||||
/* failed in cache but found on disk - fill cache. */
|
||||
trace(TraceLump, "lookupscore loaded");
|
||||
addstat(StatIcacheFill, 1);
|
||||
|
||||
addstat(StatIcacheFill, 1);
|
||||
|
||||
trace(TraceLump, "lookupscore loaded");
|
||||
|
||||
/*
|
||||
* no one else can load an entry for this score,
|
||||
* since we have the overall score lock.
|
||||
*/
|
||||
qlock(&icache.lock);
|
||||
|
||||
/*
|
||||
* If we notice that all the hits are coming from one arena,
|
||||
* load the table of contents for that arena into the cache.
|
||||
*/
|
||||
ie = icachealloc(&d.ia, score);
|
||||
if(icacheprefetch){
|
||||
icache.last[icache.nlast++%nelem(icache.last)] = amapitoa(mainindex, ie->ia.addr, &aa);
|
||||
aa = ie->ia.addr - aa; /* compute base addr of arena */
|
||||
for(i=0; i<nelem(icache.last); i++)
|
||||
if(icache.last[i] != icache.last[0])
|
||||
break;
|
||||
if(i==nelem(icache.last) && icache.lastload != icache.last[0]){
|
||||
load = icache.last[0];
|
||||
icache.lastload = load;
|
||||
/*
|
||||
* no one else can load an entry for this score,
|
||||
* since we have this score's lump's lock.
|
||||
*/
|
||||
qlock(&icache.lock);
|
||||
|
||||
/*
|
||||
* If we notice that all the hits are coming from one arena,
|
||||
* load the table of contents for that arena into the cache.
|
||||
*/
|
||||
load = nil;
|
||||
h = hashbits(score, icache.bits);
|
||||
ie = icachealloc(&d.ia, score);
|
||||
if(icacheprefetch){
|
||||
icache.last[icache.nlast++%nelem(icache.last)] = amapitoa(mainindex, ie->ia.addr, &aa);
|
||||
aa = ie->ia.addr - aa; /* compute base addr of arena */
|
||||
for(i=0; i<nelem(icache.last); i++)
|
||||
if(icache.last[i] != icache.last[0])
|
||||
break;
|
||||
if(i==nelem(icache.last) && icache.lastload != icache.last[0]){
|
||||
load = icache.last[0];
|
||||
icache.lastload = load;
|
||||
}
|
||||
}
|
||||
|
||||
ie->next = icache.heads[h];
|
||||
icache.heads[h] = ie;
|
||||
|
||||
*ia = ie->ia;
|
||||
*rac = ie->rac;
|
||||
|
||||
qunlock(&icache.lock);
|
||||
if(load){
|
||||
trace(TraceProc, "preload 0x%llux", aa);
|
||||
loadarenaclumps(load, aa);
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
ie->next = icache.heads[h];
|
||||
icache.heads[h] = ie;
|
||||
|
||||
*ia = ie->ia;
|
||||
*rac = ie->rac;
|
||||
|
||||
qunlock(&icache.lock);
|
||||
|
||||
if(load){
|
||||
trace(TraceProc, "preload 0x%llux", aa);
|
||||
loadarenaclumps(load, aa);
|
||||
}
|
||||
out:
|
||||
ms = msec() - ms;
|
||||
addstat2(StatIcacheRead, 1, StatIcacheReadTime, ms);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -674,7 +674,10 @@ bucklook(u8int *score, int otype, u8int *data, int n)
|
|||
{
|
||||
int i, r, l, m, h, c, cc, type;
|
||||
|
||||
type = vttodisktype(otype);
|
||||
if(otype == -1)
|
||||
type = -1;
|
||||
else
|
||||
type = vttodisktype(otype);
|
||||
l = 0;
|
||||
r = n - 1;
|
||||
while(l <= r){
|
||||
|
@ -692,7 +695,7 @@ bucklook(u8int *score, int otype, u8int *data, int n)
|
|||
}
|
||||
}
|
||||
cc = data[h + IEntryTypeOff];
|
||||
if(type != cc){
|
||||
if(type != cc && type != -1){
|
||||
if(type > cc)
|
||||
l = m + 1;
|
||||
else
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
int syncwrites = 0;
|
||||
int queuewrites = 0;
|
||||
int writestodevnull = 0;
|
||||
int verifywrites = 0;
|
||||
|
||||
static Packet *readilump(Lump *u, IAddr *ia, u8int *score, int rac);
|
||||
|
||||
/*
|
||||
* Some of this logic is duplicated in hdisk.c
|
||||
*/
|
||||
Packet*
|
||||
readlump(u8int *score, int type, u32int size, int *cached)
|
||||
{
|
||||
|
@ -133,11 +137,13 @@ writeqlump(Lump *u, Packet *p, int creator, uint ms)
|
|||
int rac;
|
||||
|
||||
if(lookupscore(u->score, u->type, &ia, &rac) == 0){
|
||||
/* assume the data is here! XXX */
|
||||
packetfree(p);
|
||||
ms = msec() - ms;
|
||||
addstat2(StatRpcWriteOld, 1, StatRpcWriteOldTime, ms);
|
||||
return 0;
|
||||
if(verifywrites == 0){
|
||||
/* assume the data is here! */
|
||||
packetfree(p);
|
||||
ms = msec() - ms;
|
||||
addstat2(StatRpcWriteOld, 1, StatRpcWriteOldTime, ms);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the read fails,
|
||||
|
|
|
@ -32,11 +32,46 @@ usage(void)
|
|||
threadexitsall("usage");
|
||||
}
|
||||
|
||||
char *tagged;
|
||||
|
||||
void
|
||||
tag(char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
||||
if(tagged){
|
||||
free(tagged);
|
||||
tagged = nil;
|
||||
}
|
||||
va_start(arg, fmt);
|
||||
tagged = vsmprint(fmt, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
void
|
||||
chat(char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
||||
if(tagged){
|
||||
write(1, tagged, strlen(tagged));
|
||||
free(tagged);
|
||||
tagged = nil;
|
||||
}
|
||||
va_start(arg, fmt);
|
||||
vfprint(1, fmt, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
#pragma varargck argpos tag 1
|
||||
#pragma varargck argpos chat 1
|
||||
|
||||
|
||||
int
|
||||
ereadpart(Part *p, u64int offset, u8int *buf, u32int count)
|
||||
{
|
||||
if(readpart(p, offset, buf, count) != count){
|
||||
print("%T readpart %s at %#llux+%ud: %r\n", p->name, offset, count);
|
||||
chat("%T readpart %s at %#llux+%ud: %r\n", p->name, offset, count);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -46,7 +81,7 @@ int
|
|||
ewritepart(Part *p, u64int offset, u8int *buf, u32int count)
|
||||
{
|
||||
if(writepart(p, offset, buf, count) != count){
|
||||
print("%T writepart %s at %#llux+%ud: %r\n", p->name, offset, count);
|
||||
chat("%T writepart %s at %#llux+%ud: %r\n", p->name, offset, count);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -84,7 +119,7 @@ copy(uvlong start, uvlong end, char *what, DigestState *ds)
|
|||
assert(astart <= end && end <= aend);
|
||||
|
||||
if(verbose && start != end)
|
||||
print("%T copy %,llud-%,llud %s\n", start, end, what);
|
||||
chat("%T copy %,llud-%,llud %s\n", start, end, what);
|
||||
|
||||
i = 0;
|
||||
memset(w, 0, sizeof w);
|
||||
|
@ -146,7 +181,7 @@ copy1(uvlong start, uvlong end, char *what, DigestState *ds)
|
|||
assert(astart <= end && end <= aend);
|
||||
|
||||
if(verbose && start != end)
|
||||
print("%T copy %,llud-%,llud %s\n", start, end, what);
|
||||
chat("%T copy %,llud-%,llud %s\n", start, end, what);
|
||||
|
||||
for(o=start; o<end; o+=n){
|
||||
n = sizeof tmp;
|
||||
|
@ -174,7 +209,7 @@ asha1(Part *p, uvlong start, uvlong end, DigestState *ds)
|
|||
assert(start < end);
|
||||
|
||||
if(verbose)
|
||||
print("%T sha1 %,llud-%,llud\n", start, end);
|
||||
chat("%T sha1 %,llud-%,llud\n", start, end);
|
||||
|
||||
for(o=start; o<end; o+=n){
|
||||
n = sizeof tmp;
|
||||
|
@ -217,31 +252,28 @@ mirror(Arena *sa, Arena *da)
|
|||
|
||||
astart = base - blocksize;
|
||||
aend = end + blocksize;
|
||||
|
||||
shaoff = 0;
|
||||
|
||||
tag("%T %s (%,llud-%,llud)\n", sa->name, astart, aend);
|
||||
|
||||
if(force){
|
||||
copy(astart, aend, "all", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
print("%T %s (%,llud-%,llud)\n", sa->name, astart, aend);
|
||||
|
||||
if(sa->diskstats.sealed && da->diskstats.sealed && scorecmp(da->score, zeroscore) != 0){
|
||||
if(scorecmp(sa->score, da->score) == 0)
|
||||
return;
|
||||
print("%T arena %s: sealed score mismatch %V vs %V\n", sa->name, sa->score, da->score);
|
||||
chat("%T arena %s: sealed score mismatch %V vs %V\n", sa->name, sa->score, da->score);
|
||||
status = "errors";
|
||||
return;
|
||||
}
|
||||
if(da->diskstats.sealed && scorecmp(da->score, zeroscore) != 0){
|
||||
print("%T arena %s: dst is sealed, src is not\n", sa->name);
|
||||
chat("%T arena %s: dst is sealed, src is not\n", sa->name);
|
||||
status = "errors";
|
||||
return;
|
||||
}
|
||||
if(sa->diskstats.used < da->diskstats.used){
|
||||
print("%T arena %s: src used %,lld < dst used %,lld\n", sa->name, sa->diskstats.used, da->diskstats.used);
|
||||
chat("%T arena %s: src used %,lld < dst used %,lld\n", sa->name, sa->diskstats.used, da->diskstats.used);
|
||||
status = "errors";
|
||||
return;
|
||||
}
|
||||
|
@ -331,16 +363,16 @@ mirror(Arena *sa, Arena *da)
|
|||
sha1(buf, blocksize, da->score, ds);
|
||||
if(scorecmp(sa->score, da->score) == 0){
|
||||
if(verbose)
|
||||
print("%T arena %s: %V\n", sa->name, da->score);
|
||||
chat("%T arena %s: %V\n", sa->name, da->score);
|
||||
scorecp(buf+blocksize-VtScoreSize, da->score);
|
||||
if(ewritepart(dst, end, buf, blocksize) < 0)
|
||||
return;
|
||||
}else{
|
||||
print("%T arena %s: sealing dst: score mismatch: %V vs %V\n", sa->name, sa->score, da->score);
|
||||
chat("%T arena %s: sealing dst: score mismatch: %V vs %V\n", sa->name, sa->score, da->score);
|
||||
memset(&xds, 0, sizeof xds);
|
||||
asha1(dst, base-blocksize, end, &xds);
|
||||
sha1(buf, blocksize, da->score, &xds);
|
||||
print("%T reseal: %V\n", da->score);
|
||||
chat("%T reseal: %V\n", da->score);
|
||||
status = "errors";
|
||||
}
|
||||
}
|
||||
|
@ -383,7 +415,7 @@ mirrormany(ArenaPart *sp, ArenaPart *dp, char *range)
|
|||
hi = strtol(s, &s, 0);
|
||||
}
|
||||
if(*s != 0){
|
||||
print("%T bad arena range: %s\n", s);
|
||||
chat("%T bad arena range: %s\n", s);
|
||||
continue;
|
||||
}
|
||||
for(i=lo; i<=hi; i++){
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<$PLAN9/src/mkhdr
|
||||
CC=9c
|
||||
|
||||
|
||||
LIBOFILES=\
|
||||
arena.$O\
|
||||
|
@ -14,6 +12,7 @@ LIBOFILES=\
|
|||
disksched.$O\
|
||||
dump.$O\
|
||||
graph.$O\
|
||||
hdisk.$O\
|
||||
httpd.$O\
|
||||
icache.$O\
|
||||
icachewrite.$O\
|
||||
|
@ -41,7 +40,7 @@ LIBOFILES=\
|
|||
|
||||
SLIB=libvs.a
|
||||
|
||||
LIB=$SLIB
|
||||
LIB=$SLIB $LIBDIR/libnventi.a
|
||||
|
||||
HFILES= dat.h\
|
||||
fns.h\
|
||||
|
@ -49,22 +48,22 @@ HFILES= dat.h\
|
|||
|
||||
TARG=\
|
||||
venti\
|
||||
fmtarenas\
|
||||
fmtbloom\
|
||||
fmtisect\
|
||||
fmtindex\
|
||||
fixarenas\
|
||||
buildindex\
|
||||
checkarenas\
|
||||
checkindex\
|
||||
clumpstats\
|
||||
findscore\
|
||||
fixarenas\
|
||||
fmtarenas\
|
||||
fmtbloom\
|
||||
fmtindex\
|
||||
fmtisect\
|
||||
mirrorarenas\
|
||||
rdarena\
|
||||
wrarena\
|
||||
syncindex\
|
||||
printarena\
|
||||
rdarena\
|
||||
syncindex\
|
||||
verifyarena\
|
||||
wrarena\
|
||||
|
||||
OFILES=
|
||||
|
||||
|
@ -72,82 +71,18 @@ BIN=$BIN/venti
|
|||
|
||||
it:V: $O.venti
|
||||
|
||||
$O.venti: # debugmalloc2.$O # debugmalloc.$O #_p9dir.$O debugmalloc.$O
|
||||
|
||||
CLEANFILES=$CLEANFILES $SLIB
|
||||
|
||||
<$PLAN9/src/mkmany
|
||||
<$PLAN9/src/cmd/mkmany
|
||||
|
||||
CFLAGS=$CFLAGS -I.
|
||||
|
||||
$SLIB: $LIBOFILES
|
||||
$AR rvc $SLIB $LIBOFILES
|
||||
ar rvc $SLIB $LIBOFILES
|
||||
|
||||
# xml.c:D: mkxml dat.h
|
||||
# ./mkxml dat.h > xml.c
|
||||
|
||||
ainstall:V: ${TARG:%=%.ainstall}
|
||||
|
||||
%.ainstall:V: $O.%
|
||||
scp $prereq amsterdam:/usr/local/bin/venti/$stem
|
||||
|
||||
test:VQ: ${TARG:%=o.%}
|
||||
slay o.venti|rc
|
||||
vtmp=/home/tmp
|
||||
test -f $vtmp/arena || dd bs=1048576 count=100 if=/dev/zero of=$vtmp/arena
|
||||
test -f $vtmp/bloom || dd bs=1048576 count=10 if=/dev/zero of=$vtmp/bloom
|
||||
test -f $vtmp/isect || dd bs=1048576 count=10 if=/dev/zero of=$vtmp/isect
|
||||
test -f $vtmp/check || dd bs=1048576 count=20 if=/dev/zero of=$vtmp/check
|
||||
echo '**********' FMTARENAS
|
||||
./o.fmtarenas -a 40M -b 8k arenas $vtmp/arena
|
||||
echo '**********' FMTBLOOM
|
||||
./o.fmtbloom -s 10M $vtmp/bloom
|
||||
echo '**********' FMTISECT
|
||||
./o.fmtisect -b 8k isect $vtmp/isect
|
||||
(
|
||||
echo index main
|
||||
echo isect $vtmp/isect
|
||||
echo arenas $vtmp/arena
|
||||
echo bloom $vtmp/bloom
|
||||
echo webroot $PLAN9/src/cmd/venti/srv/www
|
||||
echo mem 64M
|
||||
echo icmem 64M
|
||||
echo bcmem 64M
|
||||
echo queuewrites
|
||||
echo addr 'tcp!*!17034'
|
||||
echo httpaddr 'tcp!*!8001'
|
||||
) >vtmp.conf
|
||||
echo '**********' FMTINDEX
|
||||
./o.fmtindex vtmp.conf
|
||||
echo '**********' VENTI
|
||||
./o.venti -c vtmp.conf >a 2>&1
|
||||
echo '**********' VAC
|
||||
venti='tcp!127.0.0.1!17034' export venti
|
||||
9 time vac /usr/local/plan9/src >a.vac
|
||||
case ${websync:-no} in
|
||||
yes)
|
||||
echo '**********' SYNC VIA WEB
|
||||
hget http://127.0.0.1:8001/flushdcache
|
||||
hget http://127.0.0.1:8001/flushicache
|
||||
hget http://127.0.0.1:8001/flushdcache
|
||||
echo '**********' KILL VENTI
|
||||
killall -9 o.venti
|
||||
;;
|
||||
no)
|
||||
echo '**********' KILL VENTI
|
||||
killall -9 o.venti
|
||||
echo '**********' SYNCINDEX
|
||||
./o.syncindex -B64M -I64M -f vtmp.conf
|
||||
;;
|
||||
esac
|
||||
echo '**********' CHECKINDEX
|
||||
./o.checkindex -B64M vtmp.conf $vtmp/check >check.out
|
||||
wc check.out
|
||||
|
||||
luadisk.o: luadisk.c
|
||||
gcc -c -ggdb -Wall -I/usr/include/lua50 luadisk.c
|
||||
|
||||
libluadisk.so: luadisk.o
|
||||
gcc -shared -o $target luadisk.o -llua50 -llualib50
|
||||
|
||||
$O.xwrarena: xwrarena.$O
|
||||
$LD -o $target xwrarena.$O
|
||||
acid:D: lumpcache.acid
|
||||
cat $prereq >$target
|
||||
|
||||
|
|
|
@ -197,14 +197,15 @@ int
|
|||
prwb(char *name, int fd, int isread, u64int offset, void *vbuf, u32int count, u32int blocksize)
|
||||
{
|
||||
char *op;
|
||||
u8int *buf, *tmp, *freetmp, *dst;
|
||||
u32int c, delta, icount, opsize;
|
||||
u8int *buf, *freetmp, *dst;
|
||||
u32int icount, opsize;
|
||||
int r;
|
||||
|
||||
icount = count;
|
||||
buf = vbuf;
|
||||
|
||||
#ifndef PLAN9PORT
|
||||
USED(blocksize);
|
||||
icount = count;
|
||||
buf = vbuf;
|
||||
op = isread ? "read" : "write";
|
||||
dst = buf;
|
||||
freetmp = nil;
|
||||
|
@ -223,8 +224,12 @@ prwb(char *name, int fd, int isread, u64int offset, void *vbuf, u32int count, u3
|
|||
goto Error;
|
||||
}
|
||||
return icount;
|
||||
#endif
|
||||
#else
|
||||
u32int c, delta;
|
||||
u8int *tmp;
|
||||
|
||||
icount = count;
|
||||
buf = vbuf;
|
||||
tmp = nil;
|
||||
freetmp = nil;
|
||||
opsize = blocksize;
|
||||
|
@ -343,6 +348,7 @@ print("FAILED isread=%d r=%d count=%d blocksize=%d\n", isread, r, count, blocksi
|
|||
if(freetmp)
|
||||
free(freetmp);
|
||||
return icount;
|
||||
#endif
|
||||
|
||||
Error:
|
||||
seterr(EAdmin, "%s %s offset 0x%llux count %ud buf %p returned %d: %r",
|
||||
|
|
|
@ -68,7 +68,7 @@ threadmain(int argc, char *argv[])
|
|||
Arena *arena;
|
||||
u64int offset, aoffset;
|
||||
Part *part;
|
||||
uchar buf[8192];
|
||||
static uchar buf[8192];
|
||||
ArenaHead head;
|
||||
|
||||
readonly = 1; /* for part.c */
|
||||
|
|
|
@ -250,10 +250,7 @@ sortiebucks(IEBucks *ib)
|
|||
ib->bucks[i].buf = nil;
|
||||
ib->off = (u64int)ib->chunks * ib->size;
|
||||
free(ib->xbuf);
|
||||
if(0){
|
||||
fprint(2, "ib->max = %lld\n", ib->max);
|
||||
fprint(2, "ib->chunks = %ud\n", ib->chunks);
|
||||
}
|
||||
|
||||
ib->buf = MKN(u8int, ib->max + U32Size);
|
||||
if(ib->buf == nil){
|
||||
seterr(EOk, "out of memory allocating final sorting buffer; try more buckets");
|
||||
|
@ -270,7 +267,6 @@ if(0){
|
|||
tot += n;
|
||||
}
|
||||
return tot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -352,7 +348,7 @@ readiebuck(IEBucks *ib, int b)
|
|||
if(m == 0)
|
||||
m = ib->usable;
|
||||
if(0) if(ib->bucks[b].total)
|
||||
fprint(2, "\tbucket %d: %d entries\n", b, ib->bucks[b].total/IEntrySize);
|
||||
fprint(2, "\tbucket %d: %lld entries\n", b, ib->bucks[b].total/IEntrySize);
|
||||
while(head != TWID32){
|
||||
if(readpart(ib->part, (u64int)head * ib->size, &ib->buf[n], m+U32Size) < 0){
|
||||
seterr(EOk, "can't read index sort bucket: %r");
|
||||
|
|
|
@ -149,8 +149,8 @@ void
|
|||
binstats(long (*fn)(Stats *s0, Stats *s1, void *arg), void *arg,
|
||||
long t0, long t1, Statbin *bin, int nbin)
|
||||
{
|
||||
long t, xt0, te, v;
|
||||
int i, j, lo, hi, m, oj;
|
||||
long xt0, t, te, v;
|
||||
int i, j, lo, hi, m;
|
||||
vlong tot;
|
||||
Statbin *b;
|
||||
|
||||
|
@ -177,7 +177,6 @@ binstats(long (*fn)(Stats *s0, Stats *s1, void *arg), void *arg,
|
|||
lo = m;
|
||||
}
|
||||
xt0 = stathist[lo%nstathist].now;
|
||||
if(0) fprint(2, "bsearch found %ld\n", xt0);
|
||||
if(xt0 >= t1){
|
||||
/* no samples */
|
||||
memset(bin, 0, nbin*sizeof bin[0]);
|
||||
|
@ -185,15 +184,12 @@ binstats(long (*fn)(Stats *s0, Stats *s1, void *arg), void *arg,
|
|||
}
|
||||
|
||||
hi = stattime+nstathist;
|
||||
te = t0;
|
||||
j = lo+1;
|
||||
for(i=0; i<nbin; i++){
|
||||
t = te;
|
||||
te = t0 + (t1-t0)*i/nbin;
|
||||
b = &bin[i];
|
||||
memset(b, 0, sizeof *b);
|
||||
tot = 0;
|
||||
oj = j;
|
||||
for(; j<hi && stathist[j%nstathist].now<te; j++){
|
||||
v = fn(&stathist[(j-1)%nstathist], &stathist[j%nstathist], arg);
|
||||
if(b->nsamp==0 || v < b->min)
|
||||
|
@ -203,7 +199,6 @@ binstats(long (*fn)(Stats *s0, Stats *s1, void *arg), void *arg,
|
|||
tot += v;
|
||||
b->nsamp++;
|
||||
}
|
||||
if(0) fprint(2, "bin%d: %ld to %ld; %d to %d - %d samples\n", i, t, te, oj, j, b->nsamp);
|
||||
if(b->nsamp)
|
||||
b->avg = tot / b->nsamp;
|
||||
if(b->nsamp==0 && i>0)
|
||||
|
|
|
@ -64,7 +64,6 @@ syncarena(Arena *arena, u64int start, u32int n, int zok, int fix)
|
|||
if(lump == nil){
|
||||
fprint(2, "%s: clump=%d failed to read correctly: %r\n", arena->name, clump);
|
||||
break;
|
||||
err |= SyncDataErr;
|
||||
}else if(cl.info.type != VtCorruptType){
|
||||
scoremem(score, lump->data, cl.info.uncsize);
|
||||
if(scorecmp(cl.info.score, score) != 0){
|
||||
|
|
|
@ -123,7 +123,6 @@ syncindex(Index *ix, int fix, int mustflush, int check)
|
|||
Arena *arena;
|
||||
AState as;
|
||||
u64int a;
|
||||
u32int clump;
|
||||
int i, e, e1, ok, ok1, flush;
|
||||
|
||||
ok = 0;
|
||||
|
@ -144,11 +143,18 @@ syncindex(Index *ix, int fix, int mustflush, int check)
|
|||
e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr);
|
||||
if(e1 == SyncHeader)
|
||||
fprint(2, "arena %s: header is out-of-date\n", arena->name);
|
||||
clump = arena->diskstats.clumps;
|
||||
if(e1)
|
||||
ok = -1;
|
||||
else{
|
||||
ok1 = syncarenaindex(ix, arena, clump, a + ix->amap[i].start, fix, &flush, check);
|
||||
/*
|
||||
* use diskstats not memstats here, because diskstats
|
||||
* is what has been indexed; memstats is what has
|
||||
* made it to disk (confusing names).
|
||||
*/
|
||||
ok1 = syncarenaindex(ix, arena,
|
||||
arena->diskstats.clumps,
|
||||
ix->amap[i].start + arena->diskstats.used,
|
||||
fix, &flush, check);
|
||||
if(ok1 < 0)
|
||||
fprint(2, "syncarenaindex: %r\n");
|
||||
fprint(2, "arena %s: wbarena in syncindex\n", arena->name);
|
||||
|
|
|
@ -6,7 +6,9 @@ void
|
|||
fmtzbinit(Fmt *f, ZBlock *b)
|
||||
{
|
||||
memset(f, 0, sizeof *f);
|
||||
#ifdef PLAN9PORT
|
||||
fmtlocaleinit(f, nil, nil, nil);
|
||||
#endif
|
||||
f->start = b->data;
|
||||
f->to = f->start;
|
||||
f->stop = (char*)f->start + b->len;
|
||||
|
|
|
@ -9,7 +9,7 @@ zeropart(Part *part, int blocksize)
|
|||
u64int addr;
|
||||
int w;
|
||||
|
||||
fprint(2, "clearing the partition\n");
|
||||
fprint(2, "clearing %s\n", part->name);
|
||||
b = alloczblock(MaxIoSize, 1, blocksize);
|
||||
|
||||
w = 0;
|
||||
|
|
Loading…
Reference in a new issue