Fix a handful of small one-time memory leaks in vbackup,

and one per-package memory leak (in writethread).
This commit is contained in:
rsc 2006-10-19 21:58:59 +00:00
parent 067d852abe
commit 6fc7da3c52
17 changed files with 94 additions and 13 deletions

View file

@ -348,6 +348,8 @@ Packet *vtrecv(VtConn*);
int vtversion(VtConn *z); int vtversion(VtConn *z);
void vtdebug(VtConn *z, char*, ...); void vtdebug(VtConn *z, char*, ...);
void vthangup(VtConn *z); void vthangup(VtConn *z);
int vtgoodbye(VtConn *z);
/* #pragma varargck argpos vtdebug 2 */ /* #pragma varargck argpos vtdebug 2 */
/* server */ /* server */
@ -412,6 +414,7 @@ struct VtBlock
u32int used; u32int used;
u32int used2; u32int used2;
u32int addr; u32int addr;
uintptr pc;
}; };
u32int vtglobaltolocal(uchar[VtScoreSize]); u32int vtglobaltolocal(uchar[VtScoreSize]);

View file

@ -62,3 +62,9 @@ qclose(Queue *q)
rwakeup(&q->r); rwakeup(&q->r);
qunlock(&q->lk); qunlock(&q->lk);
} }
void
qfree(Queue *q)
{
vtfree(q);
}

View file

@ -20,3 +20,4 @@ Queue *qalloc(void);
void qclose(Queue*); void qclose(Queue*);
Block *qread(Queue*, u32int*); Block *qread(Queue*, u32int*);
void qwrite(Queue*, Block*, u32int); void qwrite(Queue*, Block*, u32int);
void qfree(Queue*);

View file

@ -284,6 +284,9 @@ threadmain(int argc, char **argv)
* wait for processes to finish * wait for processes to finish
*/ */
wlock(&endlk); wlock(&endlk);
qfree(qcmp);
qfree(qventi);
if(statustime) if(statustime)
print("# %T procs exited: %d blocks changed, %d read, %d written, %d skipped, %d copied\n", print("# %T procs exited: %d blocks changed, %d read, %d written, %d skipped, %d copied\n",
@ -297,6 +300,8 @@ threadmain(int argc, char **argv)
sysfatal("vtfileflush: %r"); sysfatal("vtfileflush: %r");
if(vtfilegetentry(vfile, &e) < 0) if(vtfilegetentry(vfile, &e) < 0)
sysfatal("vtfilegetentry: %r"); sysfatal("vtfilegetentry: %r");
vtfileunlock(vfile);
vtfileclose(vfile);
b = vtcacheallocblock(c, VtDirType); b = vtcacheallocblock(c, VtDirType);
if(b == nil) if(b == nil)
@ -336,6 +341,19 @@ threadmain(int argc, char **argv)
sysfatal("vtsync: %r"); sysfatal("vtsync: %r");
if(statustime) if(statustime)
print("# %T synced\n"); print("# %T synced\n");
fsysclose(fsys);
diskclose(disk);
vtcachefree(zcache);
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); threadexitsall(nil);
} }
@ -416,6 +434,7 @@ writethread(void *v)
} }
if(vtwritepacket(z, wr.score, wr.type, wr.p) < 0) if(vtwritepacket(z, wr.score, wr.type, wr.p) < 0)
sysfatal("vtwritepacket: %r"); sysfatal("vtwritepacket: %r");
packetfree(wr.p);
} }
} }
@ -472,6 +491,7 @@ ventiproc(void *dummy)
vtcachesetwrite(zcache, nil); vtcachesetwrite(zcache, nil);
for(i=0; i<nwritethread; i++) for(i=0; i<nwritethread; i++)
send(writechan, nil); send(writechan, nil);
chanfree(writechan);
if(statustime) if(statustime)
print("# %T venti proc exiting - nsend %d nrecv %d\n", nsend, nrecv); print("# %T venti proc exiting - nsend %d nrecv %d\n", nsend, nrecv);
runlock(&endlk); runlock(&endlk);
@ -534,6 +554,7 @@ mountplace(char *dev)
if(threadspawnl(fd, "sh", "sh", "-c", cmd, nil) < 0) if(threadspawnl(fd, "sh", "sh", "-c", cmd, nil) < 0)
sysfatal("exec mount|awk (to find mtpt of %s): %r", dev); sysfatal("exec mount|awk (to find mtpt of %s): %r", dev);
/* threadspawnl closed p[1] */ /* threadspawnl closed p[1] */
free(cmd);
n = readn(p[0], buf, sizeof buf-1); n = readn(p[0], buf, sizeof buf-1);
close(p[0]); close(p[0]);
if(n <= 0) if(n <= 0)

View file

@ -5,7 +5,7 @@
/* /*
* Disk cache. Caches by offset, so higher levels have * Disk cache. Caches by offset, so higher levels have
* to deal with alignment issues (if we get asked for the * to deal with alignment issues (if we get asked for the
* blocks at offsets 0 and 1, we'll do two reads. * blocks at offsets 0 and 1, we'll do two reads).
*/ */
typedef struct DiskCache DiskCache; typedef struct DiskCache DiskCache;

View file

@ -46,6 +46,7 @@ fsysopenffs(Disk *disk)
fsys->_readfile = ffsreadfile; fsys->_readfile = ffsreadfile;
fsys->_readlink = ffsreadlink; fsys->_readlink = ffsreadlink;
fsys->_readdir = ffsreaddir; fsys->_readdir = ffsreaddir;
fsys->_close = ffsclose;
fsys->fileblock = ffsxfileblock; fsys->fileblock = ffsxfileblock;
if(ffssync(fsys) < 0) if(ffssync(fsys) < 0)

View file

@ -167,7 +167,7 @@ fprint(2, "cachecheck: nheap %d refed %d nblocks %d\n", c->nheap, refed, c->nblo
for(i = 0; i < c->nblock; i++){ for(i = 0; i < c->nblock; i++){
b = &c->block[i]; b = &c->block[i];
if(b->ref){ if(b->ref){
if(1)fprint(2, "a=%ud %V ref=%d\n", b->addr, b->score, b->ref); if(1)fprint(2, "a=%ud %V ref=%d pc=%#lux\n", b->addr, b->score, b->ref, (ulong)b->pc);
refed++; refed++;
} }
} }
@ -333,6 +333,7 @@ vtcachelocal(VtCache *c, u32int addr, int type)
qlock(&b->lk); qlock(&b->lk);
b->nlock = 1; b->nlock = 1;
b->pc = getcallerpc(&c);
return b; return b;
} }
@ -352,7 +353,7 @@ vtcacheallocblock(VtCache *c, int type)
qlock(&b->lk); qlock(&b->lk);
b->nlock = 1; b->nlock = 1;
b->pc = getcallerpc(&b);
return b; return b;
} }
@ -374,7 +375,10 @@ vtcacheglobal(VtCache *c, uchar score[VtScoreSize], int type)
if(addr != NilBlock){ if(addr != NilBlock){
if(vttracelevel) if(vttracelevel)
fprint(2, "vtcacheglobal %V %d => local\n", score, type); fprint(2, "vtcacheglobal %V %d => local\n", score, type);
return vtcachelocal(c, addr, type); b = vtcachelocal(c, addr, type);
if(b)
b->pc = getcallerpc(&c);
return b;
} }
h = (u32int)(score[0]|(score[1]<<8)|(score[2]<<16)|(score[3]<<24)) % c->nhash; h = (u32int)(score[0]|(score[1]<<8)|(score[2]<<16)|(score[3]<<24)) % c->nhash;
@ -404,6 +408,7 @@ vtcacheglobal(VtCache *c, uchar score[VtScoreSize], int type)
} }
if(vttracelevel) if(vttracelevel)
fprint(2, "vtcacheglobal %V %d => found in cache; returning\n", score, type); fprint(2, "vtcacheglobal %V %d => found in cache; returning\n", score, type);
b->pc = getcallerpc(&c);
return b; return b;
} }
@ -451,6 +456,7 @@ vtcacheglobal(VtCache *c, uchar score[VtScoreSize], int type)
b->nlock = 1; b->nlock = 1;
if(vttracelevel) if(vttracelevel)
fprint(2, "vtcacheglobal %V %d => loaded into cache; returning\n", score, type); fprint(2, "vtcacheglobal %V %d => loaded into cache; returning\n", score, type);
b->pc = getcallerpc(&b);
return b; return b;
} }
@ -573,6 +579,7 @@ vtblockcopy(VtBlock *b)
} }
memmove(bb->data, b->data, b->c->blocksize); memmove(bb->data, b->data, b->c->blocksize);
vtblockput(b); vtblockput(b);
bb->pc = getcallerpc(&b);
return bb; return bb;
} }

View file

@ -169,3 +169,12 @@ vtconnect(VtConn *z)
return 0; return 0;
} }
int
vtgoodbye(VtConn *z)
{
VtFcall tx, rx;
tx.msgtype = VtTgoodbye;
vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */
return 0;
}

View file

@ -32,15 +32,19 @@ vtfreeconn(VtConn *z)
{ {
vthangup(z); vthangup(z);
qlock(&z->lk); qlock(&z->lk);
for(;;){ /*
* Wait for send and recv procs to notice
* the hangup and clear out the queues.
*/
while(z->readq || z->writeq){
if(z->readq) if(z->readq)
_vtqhangup(z->readq); _vtqhangup(z->readq);
else if(z->writeq) if(z->writeq)
_vtqhangup(z->writeq); _vtqhangup(z->writeq);
else
break;
rsleep(&z->rpcfork); rsleep(&z->rpcfork);
} }
packetfree(z->part); packetfree(z->part);
vtfree(z->version);
vtfree(z->sid);
vtfree(z); vtfree(z);
} }

View file

@ -205,6 +205,7 @@ vtfcallunpack(VtFcall *f, Packet *p)
Err: Err:
werrstr("bad packet"); werrstr("bad packet");
vtfcallclear(f);
return -1; return -1;
} }

View file

@ -699,7 +699,7 @@ vtfileblock(VtFile *r, u32int bn, int mode)
i = mkindices(&e, bn, index); i = mkindices(&e, bn, index);
if(i < 0) if(i < 0)
return nil; goto Err;
if(i > DEPTH(e.type)){ if(i > DEPTH(e.type)){
if(mode == VtOREAD){ if(mode == VtOREAD){
werrstr("bad address 0x%lux", (ulong)bn); werrstr("bad address 0x%lux", (ulong)bn);
@ -726,6 +726,7 @@ assert(b->type == VtDirType);
vtblockput(b); vtblockput(b);
b = bb; b = bb;
} }
b->pc = getcallerpc(&r);
return b; return b;
Err: Err:
vtblockput(b); vtblockput(b);
@ -833,6 +834,7 @@ fileloadblock(VtFile *r, int mode)
b = vtcacheglobal(r->c, r->score, VtDirType); b = vtcacheglobal(r->c, r->score, VtDirType);
if(b == nil) if(b == nil)
return nil; return nil;
b->pc = getcallerpc(&r);
return b; return b;
} }
assert(r->parent != nil); assert(r->parent != nil);
@ -902,6 +904,7 @@ vtfilelock(VtFile *r, int mode)
*/ */
assert(r->b == nil); assert(r->b == nil);
r->b = b; r->b = b;
b->pc = getcallerpc(&r);
return 0; return 0;
} }
@ -948,6 +951,8 @@ vtfilelock2(VtFile *r, VtFile *rr, int mode)
*/ */
r->b = b; r->b = b;
rr->b = bb; rr->b = bb;
b->pc = getcallerpc(&r);
bb->pc = getcallerpc(&r);
return 0; return 0;
} }

View file

@ -1,4 +1,5 @@
#include <u.h> #include <u.h>
#include <sys/socket.h>
#include <libc.h> #include <libc.h>
#include <venti.h> #include <venti.h>
#include "queue.h" #include "queue.h"
@ -8,6 +9,9 @@ vthangup(VtConn *z)
{ {
qlock(&z->lk); qlock(&z->lk);
z->state = VtStateClosed; z->state = VtStateClosed;
/* try to make the read in vtsendproc fail */
shutdown(SHUT_WR, z->infd);
shutdown(SHUT_WR, z->outfd);
if(z->infd >= 0) if(z->infd >= 0)
close(z->infd); close(z->infd);
if(z->outfd >= 0 && z->outfd != z->infd) if(z->outfd >= 0 && z->outfd != z->infd)
@ -20,3 +24,4 @@ vthangup(VtConn *z)
_vtqhangup(z->readq); _vtqhangup(z->readq);
qunlock(&z->lk); qunlock(&z->lk);
} }

View file

@ -756,7 +756,6 @@ packetcmp(Packet *pkt0, Packet *pkt1)
} }
} }
} }
static Frag * static Frag *
fragalloc(Packet *p, int n, int pos, Frag *next) fragalloc(Packet *p, int n, int pos, Frag *next)

View file

@ -29,6 +29,20 @@ _vtqalloc(void)
return q; return q;
} }
void
_vtqfree(Queue *q)
{
Qel *e;
/* Leaks the pointers e->p! */
while(q->head){
e = q->head;
q->head = e->next;
free(e);
}
free(q);
}
int int
_vtqsend(Queue *q, void *p) _vtqsend(Queue *q, void *p)
{ {

View file

@ -4,3 +4,4 @@ int _vtqsend(Queue*, void*);
void *_vtqrecv(Queue*); void *_vtqrecv(Queue*);
void _vtqhangup(Queue*); void _vtqhangup(Queue*);
void *_vtnbqrecv(Queue*); void *_vtnbqrecv(Queue*);
void _vtqfree(Queue*);

View file

@ -59,12 +59,15 @@ _vtrpc(VtConn *z, Packet *p, VtFcall *tx)
if(top == buf){ if(top == buf){
werrstr("first two bytes must be in same packet fragment"); werrstr("first two bytes must be in same packet fragment");
packetfree(p); packetfree(p);
vtfree(r);
return nil; return nil;
} }
top[1] = tag; top[1] = tag;
qunlock(&z->lk); qunlock(&z->lk);
if(vtsend(z, p) < 0) if(vtsend(z, p) < 0){
vtfree(r);
return nil; return nil;
}
qlock(&z->lk); qlock(&z->lk);
/* wait for the muxer to give us our packet */ /* wait for the muxer to give us our packet */
@ -85,6 +88,7 @@ _vtrpc(VtConn *z, Packet *p, VtFcall *tx)
if((p = vtrecv(z)) == nil){ if((p = vtrecv(z)) == nil){
werrstr("unexpected eof on venti connection"); werrstr("unexpected eof on venti connection");
z->muxer = 0; z->muxer = 0;
vtfree(r);
return nil; return nil;
} }
qlock(&z->lk); qlock(&z->lk);

View file

@ -147,7 +147,7 @@ vtrecvproc(void *v)
_vtqhangup(q); _vtqhangup(q);
while((p = _vtnbqrecv(q)) != nil) while((p = _vtnbqrecv(q)) != nil)
packetfree(p); packetfree(p);
vtfree(q); _vtqfree(q);
z->readq = nil; z->readq = nil;
rwakeup(&z->rpcfork); rwakeup(&z->rpcfork);
qunlock(&z->lk); qunlock(&z->lk);
@ -178,7 +178,7 @@ vtsendproc(void *v)
_vtqhangup(q); _vtqhangup(q);
while((p = _vtnbqrecv(q)) != nil) while((p = _vtnbqrecv(q)) != nil)
packetfree(p); packetfree(p);
vtfree(q); _vtqfree(q);
z->writeq = nil; z->writeq = nil;
rwakeup(&z->rpcfork); rwakeup(&z->rpcfork);
qunlock(&z->lk); qunlock(&z->lk);