ref: 1a4e1fc2e52ab80b55ef0d7fdccca973267fb4cc
dir: /ctl.c/
#include "all.h" enum { MAXARGS = 16 }; extern Extents memunits; static int echo; enum { Cdf, Cchatty, Csync, Chalt, Cusers, Cmax }; int cmdsync(Cmdbuf *) { u64 n; while((n=sync()) > 0){ // if(chatty9p > 1) dprint("sync(): finds %llud locked blocks\n", n); sleep(1000); } return 1; } int cmdhalt(Cmdbuf *) { shutdown(); return 1; } int cmdchatty(Cmdbuf *) { extern int chatty9p; chatty9p = !chatty9p; return 1; } int cmdusers(Cmdbuf *) { syncusers(); return 1; } Cmdtab cmds[] = { {Cchatty, "chatty", 1}, {Csync, "sync", 1}, {Chalt, "halt", 1}, {Cusers, "users", 1}, }; int runcmd(int idx, Cmdbuf *cb) { switch(idx){ case Cchatty: return cmdchatty(cb); break; case Csync: return cmdsync(cb); break; case Chalt: return cmdhalt(cb); break; case Cusers: return cmdusers(cb); break; default: dprint("unknown idx %d\n", idx); } return 0; }; void ctlread(Req *req) { u64 nfree, used; char *buf; int n; nfree = nfrees(&frees); used = config.nblocks - nfree; buf = emalloc9p(MiB); /* n = snprint(buf, MiB, "pending writes %llud blocks\n", pendingwrites());*/ n = snprint(buf, MiB, "hash buckets:\n"); n += showhashbuckets(buf+n, MiB-n); n += snprint(buf+n, MiB-n, "memunits extents:\n"); n += saveextents(&memunits, buf+n, MiB-n); n += snprint(buf+n, MiB-n, "frees extents:\n"); n += saveextents(&frees, buf+n, MiB-n); if(config.size > TiB) n += snprint(buf+n, MiB-n, "(blocks) free %ulld, used %ulld, total %ulld\n" "(MiB) free %ulld, used %ulld, total %ulld\n" "(GiB) free %ulld, used %ulld, total %ulld\n" "(TiB) free %ulld, used %ulld, total %ulld\n", nfree, used, config.nblocks, nfree * Blocksize / MiB, used * Blocksize / MiB, config.size / MiB, nfree * Blocksize / GiB, used * Blocksize / GiB, config.size / GiB, nfree * Blocksize / TiB, used * Blocksize / TiB, config.size / TiB ); else if(config.size > GiB) n += snprint(buf+n, MiB-n, "(blocks) free %ulld, used %ulld, total %ulld\n" "(MiB) free %ulld, used %ulld, total %ulld\n" "(GiB) free %ulld, used %ulld, total %ulld\n", nfree, used, config.nblocks, nfree * Blocksize / MiB, used * Blocksize / MiB, config.size / MiB, nfree * Blocksize / GiB, used * Blocksize / GiB, config.size / GiB ); else if(config.size > MiB) n += snprint(buf+n, MiB-n, "(blocks) free %ulld, used %ulld, total %ulld\n" "(MiB) free %ulld, used %ulld, total %ulld\n", nfree, used, config.nblocks, nfree * Blocksize / MiB, used * Blocksize / MiB, config.size / MiB ); else n += snprint(buf+n, MiB-n, "(blocks) free %ulld, used %ulld, total %ulld\n" "(KiB) free %ulld, used %ulld, total %ulld\n", nfree, used, config.nblocks, nfree * Blocksize / KiB, used * Blocksize / KiB, config.size / KiB ); if(req->ifcall.offset < n){ req->ofcall.count = min(req->ifcall.count,n); memcpy(req->ofcall.data, buf+req->ifcall.offset, req->ofcall.count); req->ofcall.offset = req->ifcall.offset+req->ofcall.count; } respond(req, nil); free(buf); } u32 mpsrvpid = 0; /* check the comments above shutdown() to understand */ void ctlwrite(Req *req) { Cmdbuf *cb; Cmdtab *ct; char srvfilename[Namelen]; int n; if(chatty9p) dprint("ctlwrite %d -%s-\n", req->ifcall.count, req->ifcall.data); while((cb = parsecmd(req->ifcall.data, req->ifcall.count)) != nil && cb->nf > 0){ ct = lookupcmd(cb, cmds, nelem(cmds)); if(ct != nil){ req->ofcall.count = req->ifcall.count; req->ofcall.offset = req->ifcall.offset+req->ifcall.count; n = runcmd(ct->index, cb); /* should respond based on n */ // dprint("ct->index %d n %d\n", ct->index, n); if(n == 1) respond(req, nil); else respondcmderror(req, cb, "%r"); if(ct->index == Chalt){ /* /srv/mafs_service file will not exist when mounted with -s */ if(mpsrvpid && snprint(srvfilename, Namelen, "/srv/%s", service) > 5){ /* this stuff is only needed when the worker is doing the shutdown() */ remove(srvfilename); close(req->srv->infd); close(req->srv->outfd); if(mpsrvpid > 0){ postnote(PNPROC, mpsrvpid, "halt"); mpsrvpid = 0; } }else{ close(1); close(0); } exits(nil); } }else{ respond(req, errstring[Einval]); } free(cb); } }