From 00a73e9c88d163cca06c9744092a4892cb66e2eb Mon Sep 17 00:00:00 2001 From: glenda Date: Sat, 15 Feb 2025 04:30:05 +0000 Subject: [PATCH] deletions, bugfixes --- mkfile | 1 + queuesrv.c | 216 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 143 insertions(+), 74 deletions(-) diff --git a/mkfile b/mkfile index 79a279696df2b6fd767d53390e08f5aee100b728..cc540a80067458733ce16696d1404754bcd4ae24 100644 --- a/mkfile +++ b/mkfile @@ -24,6 +24,7 @@ clean:V: qclean:V: rm -f /srv/queue unmount /n || echo -n + slay queuesrv | rc qdev:V: mk queuesrv queuesrv -D || echo -n diff --git a/queuesrv.c b/queuesrv.c index 7365fbe8c5c5253c07caf605994581286243dcf2..be1ab28458e0b06a3156f07bb2c3a6971f103bae 100644 --- a/queuesrv.c +++ b/queuesrv.c @@ -14,33 +14,32 @@ enum { typedef struct { int state; usize length; - Fid* members[]; + Fid *members[]; } Queue; // typeof(fid->aux) typedef struct { usize length; - Req* members[]; + Req *members[]; } Inflight; typedef struct { - char* name; - File* file; + char *name; + File *file; } QueueDesc; Srv s; int stdio; -char* service; +char *service; -// FIXME: dynamically allocate queues int maxname; -int maxqueues; -QueueDesc* queues; -char* ctlbuf; +int queueslen; +QueueDesc *queues; +char *ctlbuf; void usage(void) { - fprint(2,"usage: queuefs [ -Ds ] [ -n maxname ] [ -q maxqueues ] [ service ]\n"); + fprint(2,"usage: queuefs [ -Ds ] [ -n maxname ] [ service ]\n"); exits("usage"); } @@ -52,7 +51,7 @@ setuptree(void) } void -main(int argc, char* argv[]) +main(int argc, char *argv[]) { ARGBEGIN{ case 's': @@ -64,12 +63,9 @@ main(int argc, char* argv[]) case 'n': maxname = atoi(EARGF(usage())); break; - case 'q': - maxqueues = atoi(EARGF(usage())); - break; default: usage(); - } ARGEND + }ARGEND switch(argc){ case 0: @@ -84,15 +80,13 @@ main(int argc, char* argv[]) if(maxname <= 0) maxname = 64; - if(maxqueues <= 0) - maxqueues = 256; fmtinstall('D', dirfmt); fmtinstall('M', dirmodefmt); - #pragma varargck type "F" Fcall* + #pragma varargck type "F" Fcall * fmtinstall('F', fcallfmt); - queues = calloc(maxqueues, sizeof(QueueDesc)); + queueslen = 0; setuptree(); @@ -100,43 +94,49 @@ main(int argc, char* argv[]) s.infd = 0; s.outfd = 1; srv(&s); - } - else{ + }else{ print("posting service %s\n", service); if(postsrv(&s, service) < 0) sysfatal("couldn't postsrv: %r"); } } -char* -newqueue(char* name) +void +ctlclear(void) +{ + if(ctlbuf != nil){ + free(ctlbuf); + ctlbuf = nil; + } +} +char * +newqueue(char *name) { int i; - Queue* queue; + Queue *queue; - for(i = 0; i < maxqueues && queues[i].file != nil; i++); - if(i == maxqueues) - return "new: too many queues"; + for(i = 0; i < queueslen && queues[i].file != nil; i++); + print("pre-realloc %d\n", queueslen); + if(i == queueslen) + queues = realloc(queues, (++queueslen) * sizeof(QueueDesc)); + print("post-realloc %d\n", queueslen); - queue = calloc(1, sizeof(Queue) + sizeof(Fid*)); + queue = calloc(1, sizeof(Queue) + sizeof(Fid *)); queue->length = 1; queues[i].file = createfile(s.tree->root, name, "none", 0444, queue); queues[i].name = name; - if(ctlbuf != nil){ - free(ctlbuf); - ctlbuf = nil; - } + ctlclear(); return nil; } uint -newmember(Fid* fid) +newmember(Fid *fid) { - File* file; - Queue* queue; - Inflight* inflight; + File *file; + Queue *queue; + Inflight *inflight; uint i; file = fid->file; @@ -147,29 +147,52 @@ newmember(Fid* fid) // reallocate queue if necessary if(i == queue->length){ queue->length *= 2; - queue = realloc(queue, sizeof(Queue) + sizeof(Fid*) * queue->length); + queue = realloc(queue, sizeof(Queue) + sizeof(Fid *) * queue->length); file->aux = queue; } queue->members[i] = fid; // setup read queue - inflight = calloc(1, sizeof(Inflight) + sizeof(Req*)); + inflight = calloc(1, sizeof(Inflight) + sizeof(Req *)); inflight->length = 1; fid->aux = inflight; - // invalidate ctlbuf - if(ctlbuf != nil) - free(ctlbuf); - ctlbuf = nil; + ctlclear(); // return spot in queue return i; } +char * +delqueue(QueueDesc* qd) +{ + uint i; + File *file; + Queue *queue; + + file = qd->file; + queue = file->aux; + + for(i = 0; i < queue->length && queue->members[i] == nil; i++); + if(i == queue->length){ + removefile(file); + free(queue); + }else + queue->state = QDeleted; + + free(qd->name); + qd->file = nil; + qd->name = nil; + + ctlclear(); + + return nil; +} + void -registerreq(Req* r) +registerreq(Req *r) { - Inflight* inflight; + Inflight *inflight; uint i; inflight = r->fid->aux; @@ -177,7 +200,7 @@ registerreq(Req* r) for(i = 0; i < inflight->length && inflight->members[i] != nil; i++); if(i == inflight->length){ inflight->length *= 2; - inflight = realloc(inflight, sizeof(Inflight) + sizeof(Req*) * inflight->length); + inflight = realloc(inflight, sizeof(Inflight) + sizeof(Req *) * inflight->length); r->fid->aux = inflight; } @@ -188,16 +211,23 @@ registerreq(Req* r) void ctlregen(void) { - char* p; + char *p; usize blen; uint nmems, i; - QueueDesc* qd; - Queue* queue; + QueueDesc *qd; + Queue *queue; - blen = (maxname + 20) * maxqueues + 10; - p = ctlbuf = calloc(blen, 1); + blen = 10; + for(i = 0; i < queueslen; i++){ + qd = queues + i; + if(qd->file != nil && qd->name != nil) + blen += strlen(qd->name) + 20; + } + + p = ctlbuf = malloc(blen); + p[0] = 0; - for(i = 0; i < maxqueues; i++){ + for(i = 0; i < queueslen; i++){ qd = queues + i; if(qd->file == nil) continue; @@ -207,11 +237,11 @@ ctlregen(void) nmems < queue->length && queue->members[nmems] != nil; nmems++); - p += sprint(p, "%s %d\n", qd->name, nmems); + p += sprint(p, "%s\t%d\n", qd->name, nmems); } } void -ctlread(Req* r) +ctlread(Req *r) { if(ctlbuf == nil) ctlregen(); @@ -221,11 +251,12 @@ ctlread(Req* r) } // FIXME: errors if command split between multiple writes void -ctlwrite(Req* r) +ctlwrite(Req *r) { - char *s, *p; + char *s, *p, *resp; int i; + //FIXME: break parsing logic out into a function if(r->ifcall.count > 5 && strncmp(r->ifcall.data, "new ", 4) == 0){ p = s = malloc(r->ifcall.count - 3); strncpy(s, r->ifcall.data + 4, r->ifcall.count - 4); @@ -240,25 +271,54 @@ ctlwrite(Req* r) return; } - for(i = 0; i < maxqueues; i++){ + for(i = 0; i < queueslen; i++){ if(queues[i].file == nil) continue; if(strcmp(s, queues[i].name) == 0) break; } - // FIXME: might leak s here - if(i == maxqueues) - respond(r, newqueue(s)); - else + if(i == queueslen){ + resp = newqueue(s); + respond(r, resp); + if(resp != nil) + free(s); + }else respond(r, nil); - } - else + }else if(r->ifcall.count > 8 && strncmp(r->ifcall.data, "delete ", 7) == 0){ + p = s = malloc(r->ifcall.count - 6); + strncpy(s, r->ifcall.data + 7, r->ifcall.count - 7); + do{ + if(isspace(*p)) + *p = '\0'; + } + while(*p++ != '\0'); + + if(strlen(s) == 0){ + respond(r, "delete: missing argument"); + return; + } + + print("trying to delete %s\n", s); + + for(i = 0; i < queueslen; i++){ + if(queues[i].file == nil) + continue; + if(strcmp(s, queues[i].name) == 0) + break; + } + + if(i != queueslen){ + respond(r, delqueue(&(queues[i]))); + free(s); + }else + respond(r, "queue does not exist"); + }else respond(r, "bad command"); } void -queueread(Req* r) +queueread(Req *r) { uint spot; char buf[32]; @@ -273,13 +333,13 @@ queueread(Req* r) registerreq(r); } void -queuewrite(Req* r) +queuewrite(Req *r) { respond(r, "queues are not writable"); } void -srvread(Req* r) +srvread(Req *r) { if(r->fid->file->aux == nil) ctlread(r); @@ -288,7 +348,7 @@ srvread(Req* r) } void -srvwrite(Req* r) +srvwrite(Req *r) { if(r->fid->file->aux == nil) ctlwrite(r); @@ -297,13 +357,11 @@ srvwrite(Req* r) } void -srvdestroyfid(Fid* fid) +srvdestroyfid(Fid *fid) { - print("dfid %p\n", fid); - - Queue* queue; - Inflight* inflight; - Req* r; + Queue *queue; + Inflight *inflight; + Req *r; uint i, j; char buf[32]; @@ -311,9 +369,10 @@ srvdestroyfid(Fid* fid) return; queue = fid->file->aux; - for(i = 0; i < queue->length && queue->members[i] != fid && queue->members[i] != nil; i++); + for(i = 0; i < queue->length && queue->members[i] != fid && queue->members[i] != nil; i++); if(i == queue->length || queue->members[i] == nil) sysfatal("bugcheck: fid->aux != nil but fid not in queue->members"); + free(fid->aux); for(; (i + 1) < queue->length && queue->members[i + 1] != nil; i++){ queue->members[i] = queue->members[i + 1]; @@ -328,14 +387,23 @@ srvdestroyfid(Fid* fid) r->ifcall.offset = 0; readstr(r, buf); respond(r, nil); + + inflight->members[j] = nil; } } queue->members[i] = nil; + + if(i == 0 && queue->state == QDeleted){ + removefile(fid->file); + free(queue); + } + + ctlclear(); } void -srvflush(Req* r) +srvflush(Req *r) { if(r->fid != nil) srvdestroyfid(r->fid);