sharpen up adding and removing consoles on the fly. in the process we're going to lose the qlock conversion, unfortunately. Reference: /n/atom/patch/applied2013/consolefsupd Date: Wed Jun 19 02:57:19 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/aux/consolefs.c Wed Jun 19 02:56:20 2013 +++ /sys/src/cmd/aux/consolefs.c Wed Jun 19 02:56:20 2013 @@ -47,14 +47,14 @@ struct Reqlist { - QLock; + Lock; Request *first; Request *last; }; struct Fid { - QLock; + Lock; Fid *next; /* hash list */ Fid *cnext; /* list of Fid's on a console */ int fid; @@ -91,6 +91,7 @@ { QLock; + int mark; Parm; int pid; /* pid of reader */ @@ -105,7 +106,7 @@ struct Fs { - QLock; + Lock; int fd; /* to kernel mount point */ int messagesize; @@ -130,7 +131,6 @@ extern void fsauth(Fs*, Request*, Fid*); extern void fsattach(Fs*, Request*, Fid*); extern void fswalk(Fs*, Request*, Fid*); -extern void fsclwalk(Fs*, Request*, Fid*); extern void fsopen(Fs*, Request*, Fid*); extern void fscreate(Fs*, Request*, Fid*); extern void fsread(Fs*, Request*, Fid*); @@ -220,14 +220,14 @@ void addreq(Reqlist *l, Request *r) { - qlock(l); + lock(l); if(l->first == nil) l->first = r; else l->last->next = r; l->last = r; r->next = nil; - qunlock(l); + unlock(l); } /* @@ -238,11 +238,11 @@ { Request *r; - qlock(l); + lock(l); r = l->first; if(r != nil) l->first = r->next; - qunlock(l); + unlock(l); return r; } @@ -254,17 +254,17 @@ { Request *or, **ll; - qlock(l); + lock(l); ll = &l->first; for(or = *ll; or; or = or->next){ if(or->f.tag == tag){ *ll = or->next; - qunlock(l); + unlock(l); return or; } ll = &or->next; } - qunlock(l); + unlock(l); return nil; } @@ -434,12 +434,12 @@ { if(c->pid > 0){ if(postnote(PNPROC, c->pid, msg) != 0) - fprint(2, "postnote failed: %r\n"); + fprint(2, "consolefs: postnote failed: cfd pid: %r\n"); c->pid = 0; } if(c->cpid > 0){ if(postnote(PNPROC, c->cpid, msg) != 0) - fprint(2, "postnote failed: %r\n"); + fprint(2, "consolefs: postnote failed: cfd cpid: %r\n"); c->cpid = 0; } close(c->fd); @@ -547,6 +547,38 @@ return c; } +void +rmconsole(Fs *fs, Console *c) +{ + Fid *f, **l, *fl; + Request *nr; + + if(debug) + fprint(2, "rmconsole %s:%s\n", c->name, c->dev); + + closeconsfds(c, "die jedi scum"); + free(c->name); + free(c->dev); + + while(f = c->flist){ + while((nr = remreq(&f->r)) != nil){ + fprint(2, "reply %#p\n", nr); + fsreply(fs, nr, "console gone"); + } + + qlock(c); + for(l = &c->flist; *l; l = &fl->cnext){ + fl = *l; + if(fl == f){ + *l = fl->cnext; + break; + } + } + qunlock(c); + } + free(c); +} + /* * buffer data from console to a client. * circular q with writer able to catch up to reader. @@ -558,7 +590,7 @@ char *rp, *wp, *ep; int pass; - qlock(f); + lock(f); rp = f->rp; wp = f->wp; ep = f->buf + sizeof(f->buf); @@ -582,7 +614,7 @@ else f->rp = wp; } - qunlock(f); + unlock(f); } /* @@ -613,6 +645,8 @@ void handler(void*, char *msg) { + if(debug) + fprint(2, "handler %s\n", msg); if(strstr(msg, "reopen") != nil || strstr(msg, "write on closed pipe") != nil) noted(NCONT); @@ -659,7 +693,7 @@ c->pid = 0; if(c->cpid > 0){ if(postnote(PNPROC, c->cpid, "reopen") != 0) - fprint(2, "postnote failed: %r\n"); + fprint(2, "consolefs: postnote failed: fsreader: %r\n"); c->cpid = 0; } qunlock(c); @@ -668,10 +702,16 @@ void readdb(Fs *fs) { + int i; + Console *c; Parm p; Ndbs s; Ndbtuple *t, *nt; + /* clear marks */ + for(i = 0; i < fs->ncons; i++) + fs->cons[i]->mark = 0; + memset(&s, 0, sizeof s); db = ndbreopendb(db); /* need for database=; botch ndbsearch should do */ @@ -694,10 +734,26 @@ else if(strcmp(nt->attr, "openondemand") == 0) p.ondemand = 1; } - if(p.dev != nil && p.name != nil) - console(fs, p); + if(p.dev != nil && p.name != nil){ + c = console(fs, p); + if(c != nil) + c->mark = 1; + } ndbfree(t); } + + /* sweep consoles */ + for(i = 0; i < fs->ncons;){ + c = fs->cons[i]; + if(c->mark){ + c->mark = 0; + i++; + continue; + } + rmconsole(fs, c); + memmove(fs->cons+i, fs->cons+i+1, (--fs->ncons - i) * sizeof c); + fs->cons[fs->ncons] = 0; + } } int dbmtime; @@ -759,11 +815,11 @@ { Fid *f, *nf; - qlock(fs); + lock(fs); for(f = fs->hash[fid%Nhash]; f; f = f->next){ if(f->fid == fid){ f->ref++; - qunlock(fs); + unlock(fs); return f; } } @@ -775,7 +831,7 @@ nf->ref = 1; nf->wp = nf->buf; nf->rp = nf->wp; - qunlock(fs); + unlock(fs); return nf; } @@ -784,9 +840,9 @@ { Fid **l, *nf; - qlock(fs); + lock(fs); if(--f->ref > 0){ - qunlock(fs); + unlock(fs); return; } for(l = &fs->hash[f->fid%Nhash]; nf = *l; l = &nf->next) @@ -794,7 +850,7 @@ *l = f->next; break; } - qunlock(fs); + unlock(fs); free(f->user); free(f); } @@ -853,9 +909,9 @@ /* hold down the fid till the clunk */ f->attached = 1; - qlock(fs); + lock(fs); f->ref++; - qunlock(fs); + unlock(fs); r->f.qid = f->qid; fsreply(fs, r, nil); @@ -1291,7 +1347,7 @@ qunlock(f->c); } - qlock(f); + lock(f); while(f->rp != f->wp){ r = remreq(&f->r); if(r == nil) @@ -1310,7 +1366,7 @@ r->f.count = p - (char*)r->buf; fsreply(fs, r, nil); } - qunlock(f); + unlock(f); } void