]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/iostats.c
ndb/dnsquery, ndb/csquery: handle long lines
[plan9front.git] / sys / src / cmd / iostats.c
index 0807f5bb197ad89c882d5d456846a2d3c1740c92..dca0525b807588385a87b64ed9daf1d478f1a705 100644 (file)
@@ -11,7 +11,6 @@
 
 enum{
        Maxfile         = 1000, /* number of Files we'll log */
-       Maxrpc          = 20000,/* number of RPCs we'll log */
 };
 
 typedef struct File File;
@@ -74,7 +73,7 @@ struct Stats
        vlong   totwrite;
        ulong   nrpc;
        vlong   nproto;
-       Rpc     rpc[Maxrpc];
+       Rpc     rpc[Tmax];
        File    file[Maxfile];
 };
 
@@ -251,7 +250,7 @@ rio(Fcall *fin, Fcall *fout)
 void
 usage(void)
 {
-       fprint(2, "usage: iostats [-d] [-f debugfile] cmds [args ...]\n");
+       fprint(2, "usage: iostats [-dC] [-f debugfile] cmds [args ...]\n");
        exits("usage");
 }
 
@@ -263,9 +262,11 @@ main(int argc, char **argv)
        char *dbfile;
        char buf[64*1024];
        float brpsec, bwpsec, bppsec;
-       int cpid, fspid, rspid, dbg, n, mflag;
+       int cpid, fspid, expid, rspid, dbg, n, mflag;
+       char *fds[3];
+       Waitmsg *w;
        File *fs;
-       Req *r, **rr;
+       Req *r;
 
        dbg = 0;
        mflag = MREPL;
@@ -291,77 +292,107 @@ main(int argc, char **argv)
                usage();
 
        if(pipe(pfd) < 0)
-               sysfatal("pipe");
+               sysfatal("pipe: %r");
+
+       /* dup std fds to be inherited to exportfs */
+       fds[0] = smprint("/fd/%d", dup(0, -1));
+       fds[1] = smprint("/fd/%d", dup(1, -1));
+       fds[2] = smprint("/fd/%d", dup(2, -1));
 
        switch(cpid = fork()) {
        case -1:
-               sysfatal("fork");
+               sysfatal("fork: %r");
        case 0:
                close(pfd[1]);
+               close(atoi(strrchr(fds[0], '/')+1));
+               close(atoi(strrchr(fds[1], '/')+1));
+               close(atoi(strrchr(fds[2], '/')+1));
+
                if(getwd(buf, sizeof(buf)) == 0)
-                       sysfatal("no working directory");
+                       sysfatal("no working directory: %r");
 
-               rfork(RFENVG|RFNAMEG|RFNOTEG);
+               rfork(RFENVG|RFNAMEG);
 
                if(mount(pfd[0], -1, "/", mflag, "") < 0)
-                       sysfatal("mount /");
+                       sysfatal("mount /: %r");
+
+               /* replace std fds with the exported ones */
+               close(0); open(fds[0], OREAD);
+               close(1); open(fds[1], OWRITE);
+               close(2); open(fds[2], OWRITE);
 
                bind("#c/pid", "/dev/pid", MREPL);
                bind("#c/ppid", "/dev/ppid", MREPL);
                bind("#e", "/env", MREPL|MCREATE);
-               close(0);
-               close(1);
-               close(2);
-               open("/fd/0", OREAD);
-               open("/fd/1", OWRITE);
-               open("/fd/2", OWRITE);
+               bind("#d", "/fd", MREPL);
+
                if(chdir(buf) < 0)
-                       sysfatal("chdir");
-               exec(argv[0], argv);
-               exec(smprint("/bin/%s", argv[0]), argv);
+                       sysfatal("chdir: %r");
+
+               exec(*argv, argv);
+               if(**argv != '/' && strncmp(*argv, "./", 2) != 0 && strncmp(*argv, "../", 3) != 0)
+                       exec(smprint("/bin/%s", *argv), argv);
                sysfatal("exec: %r");
        default:
                close(pfd[0]);
        }
 
-       switch(fspid = fork()) {
-       default:
-               while(cpid != waitpid())
-                       ;
-               postnote(PNPROC, fspid, DONESTR);
-               while(fspid != waitpid())
-                       ;
-               exits(0);
-       case -1:
-               sysfatal("fork");
-       case 0:
-               notify(catcher);
-               break;
-       }
-
+       /* isolate us from interrupts */
+       rfork(RFNOTEG);
        if(pipe(efd) < 0)
-               sysfatal("pipe");
+               sysfatal("pipe: %r");
 
        /* spawn exportfs */
-       switch(fork()) {
+       switch(expid = fork()) {
        default:
                close(efd[0]);
+               close(atoi(strrchr(fds[0], '/')+1));
+               close(atoi(strrchr(fds[1], '/')+1));
+               close(atoi(strrchr(fds[2], '/')+1));
                break;
        case -1:
-               sysfatal("fork");
+               sysfatal("fork: %r");
        case 0:
                dup(efd[0], 0);
                close(efd[0]);
                close(efd[1]);
+               close(pfd[1]);
                if(dbg){
                        execl("/bin/exportfs", "exportfs", "-df", dbfile, "-r", "/", nil);
                } else {
                        execl("/bin/exportfs", "exportfs", "-r", "/", nil);
                }
-               exits(0);
+               sysfatal("exec: %r");
        }
 
-       fmtinstall('F', fcallfmt);
+       switch(fspid = fork()) {
+       default:
+               close(pfd[1]);
+               close(efd[1]);
+
+               buf[0] = '\0';
+               while((w = wait()) != nil && (cpid != -1 || fspid != -1 || expid != -1)){
+                       if(w->pid == fspid)
+                               fspid = -1;
+                       else if(w->pid == expid)
+                               expid = -1;
+                       else if(w->pid == cpid){
+                               cpid = -1;
+                               strcpy(buf, w->msg);
+                               if(fspid != -1)
+                                       postnote(PNPROC, fspid, DONESTR);
+                       }
+                       if(buf[0] == '\0')
+                               strcpy(buf, w->msg);
+                       free(w);
+               }
+               exits(buf);
+       case -1:
+               sysfatal("fork: %r");
+       case 0:
+               notify(catcher);
+               break;
+       }
 
        stats->rpc[Tversion].name = "version";
        stats->rpc[Tauth].name = "auth";
@@ -377,7 +408,7 @@ main(int argc, char **argv)
        stats->rpc[Tstat].name = "stat";
        stats->rpc[Twstat].name = "wstat";
 
-       for(n = 0; n < Maxrpc; n++)
+       for(n = 0; n < nelem(stats->rpc); n++)
                stats->rpc[n].lo = 10000000000LL;
 
        switch(rspid = rfork(RFPROC|RFMEM)) {
@@ -386,6 +417,7 @@ main(int argc, char **argv)
                while(!done){
                        uchar tmp[sizeof(buf)];
                        Fcall f;
+                       Req **rr;
 
                        n = read(efd[1], buf, sizeof(buf));
                        if(n < 0)
@@ -440,7 +472,7 @@ main(int argc, char **argv)
                        if(write(pfd[1], buf, n) != n)
                                break;
                }
-               exits(0);
+               exits(nil);
        default:
                /* read request from mount and pass to exportfs */
                while(!done){
@@ -487,7 +519,7 @@ main(int argc, char **argv)
        bwpsec = (double)stats->totwrite / (((float)rpc->time/1e9)+.000001);
 
        ttime = 0;
-       for(n = 0; n < Maxrpc; n++) {
+       for(n = 0; n < nelem(stats->rpc); n++) {
                rpc = &stats->rpc[n];
                if(rpc->count == 0)
                        continue;
@@ -504,7 +536,7 @@ main(int argc, char **argv)
        fprint(2, "%-10s %5s %5s %5s %5s %5s          T       R\n", 
              "Message", "Count", "Low", "High", "Time", "Averg");
 
-       for(n = 0; n < Maxrpc; n++) {
+       for(n = 0; n < nelem(stats->rpc); n++) {
                rpc = &stats->rpc[n];
                if(rpc->count == 0)
                        continue;
@@ -523,6 +555,14 @@ main(int argc, char **argv)
        for(fs = stats->file; fs < &stats->file[Maxfile]; fs++){
                if(fs->nopen == 0)
                        break;
+
+               if(strcmp(fs->path, fds[0]) == 0)
+                       fs->path = "stdin";
+               else if(strcmp(fs->path, fds[1]) == 0)
+                       fs->path = "stdout";
+               else if(strcmp(fs->path, fds[2]) == 0)
+                       fs->path = "stderr";
+
                fprint(2, "%5lud %8lud %8llud %8lud %8llud %s\n",
                        fs->nopen,
                        fs->nread, fs->bread,
@@ -530,5 +570,5 @@ main(int argc, char **argv)
                        fs->path);
        }
 
-       exits(0);
+       exits(nil);
 }