diff options
author | rsc <devnull@localhost> | 2006-10-19 21:58:59 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2006-10-19 21:58:59 +0000 |
commit | 6fc7da3c529ca7c610e8172f5b02980c75597dd5 (patch) | |
tree | 6e06f1a96414ceb59a8016fb257b46b6f87f9a1c | |
parent | 067d852abe242ee1d267bcc0d652cd6bb31b7e17 (diff) | |
download | plan9port-6fc7da3c529ca7c610e8172f5b02980c75597dd5.tar.gz plan9port-6fc7da3c529ca7c610e8172f5b02980c75597dd5.tar.bz2 plan9port-6fc7da3c529ca7c610e8172f5b02980c75597dd5.zip |
Fix a handful of small one-time memory leaks in vbackup,
and one per-package memory leak (in writethread).
-rw-r--r-- | include/venti.h | 3 | ||||
-rw-r--r-- | src/cmd/vbackup/queue.c | 6 | ||||
-rw-r--r-- | src/cmd/vbackup/queue.h | 1 | ||||
-rw-r--r-- | src/cmd/vbackup/vbackup.c | 21 | ||||
-rw-r--r-- | src/libdiskfs/cache.c | 2 | ||||
-rw-r--r-- | src/libdiskfs/ffs.c | 1 | ||||
-rw-r--r-- | src/libventi/cache.c | 13 | ||||
-rw-r--r-- | src/libventi/client.c | 9 | ||||
-rw-r--r-- | src/libventi/conn.c | 12 | ||||
-rw-r--r-- | src/libventi/fcall.c | 1 | ||||
-rw-r--r-- | src/libventi/file.c | 7 | ||||
-rw-r--r-- | src/libventi/hangup.c | 5 | ||||
-rw-r--r-- | src/libventi/packet.c | 1 | ||||
-rw-r--r-- | src/libventi/queue.c | 14 | ||||
-rw-r--r-- | src/libventi/queue.h | 1 | ||||
-rw-r--r-- | src/libventi/rpc.c | 6 | ||||
-rw-r--r-- | src/libventi/send.c | 4 |
17 files changed, 94 insertions, 13 deletions
diff --git a/include/venti.h b/include/venti.h index 9fea5bcf..af5bb788 100644 --- a/include/venti.h +++ b/include/venti.h @@ -348,6 +348,8 @@ Packet *vtrecv(VtConn*); int vtversion(VtConn *z); void vtdebug(VtConn *z, char*, ...); void vthangup(VtConn *z); +int vtgoodbye(VtConn *z); + /* #pragma varargck argpos vtdebug 2 */ /* server */ @@ -412,6 +414,7 @@ struct VtBlock u32int used; u32int used2; u32int addr; + uintptr pc; }; u32int vtglobaltolocal(uchar[VtScoreSize]); diff --git a/src/cmd/vbackup/queue.c b/src/cmd/vbackup/queue.c index 91fa221d..d9fcd404 100644 --- a/src/cmd/vbackup/queue.c +++ b/src/cmd/vbackup/queue.c @@ -62,3 +62,9 @@ qclose(Queue *q) rwakeup(&q->r); qunlock(&q->lk); } + +void +qfree(Queue *q) +{ + vtfree(q); +} diff --git a/src/cmd/vbackup/queue.h b/src/cmd/vbackup/queue.h index 6b2317c3..00320069 100644 --- a/src/cmd/vbackup/queue.h +++ b/src/cmd/vbackup/queue.h @@ -20,3 +20,4 @@ Queue *qalloc(void); void qclose(Queue*); Block *qread(Queue*, u32int*); void qwrite(Queue*, Block*, u32int); +void qfree(Queue*); diff --git a/src/cmd/vbackup/vbackup.c b/src/cmd/vbackup/vbackup.c index 9e4c3b00..4c9fd386 100644 --- a/src/cmd/vbackup/vbackup.c +++ b/src/cmd/vbackup/vbackup.c @@ -284,6 +284,9 @@ threadmain(int argc, char **argv) * wait for processes to finish */ wlock(&endlk); + + qfree(qcmp); + qfree(qventi); if(statustime) 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"); if(vtfilegetentry(vfile, &e) < 0) sysfatal("vtfilegetentry: %r"); + vtfileunlock(vfile); + vtfileclose(vfile); b = vtcacheallocblock(c, VtDirType); if(b == nil) @@ -336,6 +341,19 @@ threadmain(int argc, char **argv) sysfatal("vtsync: %r"); if(statustime) 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); } @@ -416,6 +434,7 @@ writethread(void *v) } if(vtwritepacket(z, wr.score, wr.type, wr.p) < 0) sysfatal("vtwritepacket: %r"); + packetfree(wr.p); } } @@ -472,6 +491,7 @@ ventiproc(void *dummy) vtcachesetwrite(zcache, nil); for(i=0; i<nwritethread; i++) send(writechan, nil); + chanfree(writechan); if(statustime) print("# %T venti proc exiting - nsend %d nrecv %d\n", nsend, nrecv); runlock(&endlk); @@ -534,6 +554,7 @@ mountplace(char *dev) if(threadspawnl(fd, "sh", "sh", "-c", cmd, nil) < 0) sysfatal("exec mount|awk (to find mtpt of %s): %r", dev); /* threadspawnl closed p[1] */ + free(cmd); n = readn(p[0], buf, sizeof buf-1); close(p[0]); if(n <= 0) diff --git a/src/libdiskfs/cache.c b/src/libdiskfs/cache.c index f1af6f1b..7b06fa4f 100644 --- a/src/libdiskfs/cache.c +++ b/src/libdiskfs/cache.c @@ -5,7 +5,7 @@ /* * Disk cache. Caches by offset, so higher levels have * 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; diff --git a/src/libdiskfs/ffs.c b/src/libdiskfs/ffs.c index 7864c719..9607cfbe 100644 --- a/src/libdiskfs/ffs.c +++ b/src/libdiskfs/ffs.c @@ -46,6 +46,7 @@ fsysopenffs(Disk *disk) fsys->_readfile = ffsreadfile; fsys->_readlink = ffsreadlink; fsys->_readdir = ffsreaddir; + fsys->_close = ffsclose; fsys->fileblock = ffsxfileblock; if(ffssync(fsys) < 0) diff --git a/src/libventi/cache.c b/src/libventi/cache.c index 24cb8c2f..809e340f 100644 --- a/src/libventi/cache.c +++ b/src/libventi/cache.c @@ -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++){ b = &c->block[i]; 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++; } } @@ -333,6 +333,7 @@ vtcachelocal(VtCache *c, u32int addr, int type) qlock(&b->lk); b->nlock = 1; + b->pc = getcallerpc(&c); return b; } @@ -352,7 +353,7 @@ vtcacheallocblock(VtCache *c, int type) qlock(&b->lk); b->nlock = 1; - + b->pc = getcallerpc(&b); return b; } @@ -374,7 +375,10 @@ vtcacheglobal(VtCache *c, uchar score[VtScoreSize], int type) if(addr != NilBlock){ if(vttracelevel) 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; @@ -404,6 +408,7 @@ vtcacheglobal(VtCache *c, uchar score[VtScoreSize], int type) } if(vttracelevel) fprint(2, "vtcacheglobal %V %d => found in cache; returning\n", score, type); + b->pc = getcallerpc(&c); return b; } @@ -451,6 +456,7 @@ vtcacheglobal(VtCache *c, uchar score[VtScoreSize], int type) b->nlock = 1; if(vttracelevel) fprint(2, "vtcacheglobal %V %d => loaded into cache; returning\n", score, type); + b->pc = getcallerpc(&b); return b; } @@ -573,6 +579,7 @@ vtblockcopy(VtBlock *b) } memmove(bb->data, b->data, b->c->blocksize); vtblockput(b); + bb->pc = getcallerpc(&b); return bb; } diff --git a/src/libventi/client.c b/src/libventi/client.c index 33963860..40ee8517 100644 --- a/src/libventi/client.c +++ b/src/libventi/client.c @@ -169,3 +169,12 @@ vtconnect(VtConn *z) return 0; } +int +vtgoodbye(VtConn *z) +{ + VtFcall tx, rx; + + tx.msgtype = VtTgoodbye; + vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */ + return 0; +} diff --git a/src/libventi/conn.c b/src/libventi/conn.c index 990e7db2..5b6d5436 100644 --- a/src/libventi/conn.c +++ b/src/libventi/conn.c @@ -32,15 +32,19 @@ vtfreeconn(VtConn *z) { vthangup(z); 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) _vtqhangup(z->readq); - else if(z->writeq) + if(z->writeq) _vtqhangup(z->writeq); - else - break; rsleep(&z->rpcfork); } packetfree(z->part); + vtfree(z->version); + vtfree(z->sid); vtfree(z); } diff --git a/src/libventi/fcall.c b/src/libventi/fcall.c index 9f721b42..65ee2d17 100644 --- a/src/libventi/fcall.c +++ b/src/libventi/fcall.c @@ -205,6 +205,7 @@ vtfcallunpack(VtFcall *f, Packet *p) Err: werrstr("bad packet"); + vtfcallclear(f); return -1; } diff --git a/src/libventi/file.c b/src/libventi/file.c index 174561ec..6604ef67 100644 --- a/src/libventi/file.c +++ b/src/libventi/file.c @@ -699,7 +699,7 @@ vtfileblock(VtFile *r, u32int bn, int mode) i = mkindices(&e, bn, index); if(i < 0) - return nil; + goto Err; if(i > DEPTH(e.type)){ if(mode == VtOREAD){ werrstr("bad address 0x%lux", (ulong)bn); @@ -726,6 +726,7 @@ assert(b->type == VtDirType); vtblockput(b); b = bb; } + b->pc = getcallerpc(&r); return b; Err: vtblockput(b); @@ -833,6 +834,7 @@ fileloadblock(VtFile *r, int mode) b = vtcacheglobal(r->c, r->score, VtDirType); if(b == nil) return nil; + b->pc = getcallerpc(&r); return b; } assert(r->parent != nil); @@ -902,6 +904,7 @@ vtfilelock(VtFile *r, int mode) */ assert(r->b == nil); r->b = b; + b->pc = getcallerpc(&r); return 0; } @@ -948,6 +951,8 @@ vtfilelock2(VtFile *r, VtFile *rr, int mode) */ r->b = b; rr->b = bb; + b->pc = getcallerpc(&r); + bb->pc = getcallerpc(&r); return 0; } diff --git a/src/libventi/hangup.c b/src/libventi/hangup.c index 5a992e73..23075864 100644 --- a/src/libventi/hangup.c +++ b/src/libventi/hangup.c @@ -1,4 +1,5 @@ #include <u.h> +#include <sys/socket.h> #include <libc.h> #include <venti.h> #include "queue.h" @@ -8,6 +9,9 @@ vthangup(VtConn *z) { qlock(&z->lk); 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) close(z->infd); if(z->outfd >= 0 && z->outfd != z->infd) @@ -20,3 +24,4 @@ vthangup(VtConn *z) _vtqhangup(z->readq); qunlock(&z->lk); } + diff --git a/src/libventi/packet.c b/src/libventi/packet.c index aa5b2a0e..99479399 100644 --- a/src/libventi/packet.c +++ b/src/libventi/packet.c @@ -756,7 +756,6 @@ packetcmp(Packet *pkt0, Packet *pkt1) } } } - static Frag * fragalloc(Packet *p, int n, int pos, Frag *next) diff --git a/src/libventi/queue.c b/src/libventi/queue.c index 6e9bfa8d..3a1f6ea5 100644 --- a/src/libventi/queue.c +++ b/src/libventi/queue.c @@ -29,6 +29,20 @@ _vtqalloc(void) 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 _vtqsend(Queue *q, void *p) { diff --git a/src/libventi/queue.h b/src/libventi/queue.h index 99e08763..2807783b 100644 --- a/src/libventi/queue.h +++ b/src/libventi/queue.h @@ -4,3 +4,4 @@ int _vtqsend(Queue*, void*); void *_vtqrecv(Queue*); void _vtqhangup(Queue*); void *_vtnbqrecv(Queue*); +void _vtqfree(Queue*); diff --git a/src/libventi/rpc.c b/src/libventi/rpc.c index faf80629..5a820a99 100644 --- a/src/libventi/rpc.c +++ b/src/libventi/rpc.c @@ -59,12 +59,15 @@ _vtrpc(VtConn *z, Packet *p, VtFcall *tx) if(top == buf){ werrstr("first two bytes must be in same packet fragment"); packetfree(p); + vtfree(r); return nil; } top[1] = tag; qunlock(&z->lk); - if(vtsend(z, p) < 0) + if(vtsend(z, p) < 0){ + vtfree(r); return nil; + } qlock(&z->lk); /* 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){ werrstr("unexpected eof on venti connection"); z->muxer = 0; + vtfree(r); return nil; } qlock(&z->lk); diff --git a/src/libventi/send.c b/src/libventi/send.c index 1d8477d5..7ada51af 100644 --- a/src/libventi/send.c +++ b/src/libventi/send.c @@ -147,7 +147,7 @@ vtrecvproc(void *v) _vtqhangup(q); while((p = _vtnbqrecv(q)) != nil) packetfree(p); - vtfree(q); + _vtqfree(q); z->readq = nil; rwakeup(&z->rpcfork); qunlock(&z->lk); @@ -178,7 +178,7 @@ vtsendproc(void *v) _vtqhangup(q); while((p = _vtnbqrecv(q)) != nil) packetfree(p); - vtfree(q); + _vtqfree(q); z->writeq = nil; rwakeup(&z->rpcfork); qunlock(&z->lk); |