Cleans up devip state functions
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 7 May 2014 23:25:05 +0000 (16:25 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 12 Sep 2014 01:57:31 +0000 (18:57 -0700)
The protocols (tcp, udp, ipifc, etc) have state functions that print out
state info about a conversation.  There are a few things wrong.
- The main thing is that the size of the print buffers can change from
  one syscall to another.  When cat reads it, it reads twice so that it
  can detect EOF.  If the filesize changed, it could get more info the
  next time.
- TCP was printing %lu instead of %u for u32s.  This was popping up as
  as very large numbers due to seeing gibberish on the stack thinking it
  was a 64 bit int.  This also changed the size of the state buffer
  frequently.
- The devices were not uniformly doing the \n or not.

kern/src/net/devip.c
kern/src/net/icmp.c
kern/src/net/tcp.c
kern/src/net/udp.c

index ab78a0d..ef3cd30 100644 (file)
@@ -676,6 +676,7 @@ static long ipread(struct chan *ch, void *a, long n, int64_t off)
        long rv;
        struct Fs *f;
        uint32_t offset = off;
+       size_t sofar;
 
        f = ipfs[ch->dev];
 
@@ -729,10 +730,15 @@ static long ipread(struct chan *ch, void *a, long n, int64_t off)
                        kfree(buf);
                        return rv;
                case Qstatus:
+                       /* this all is a bit screwed up since the size of some state's
+                        * buffers will change from one invocation to another.  a reader
+                        * will come in and read the entire buffer.  then it will come again
+                        * and read from the next offset, expecting EOF.  if the buffer
+                        * changed sizes, it'll reprint the end of the buffer slightly. */
                        buf = kzmalloc(Statelen, 0);
                        x = f->p[PROTO(ch->qid)];
                        c = x->conv[CONV(ch->qid)];
-                       (*x->state) (c, buf, Statelen - 2);
+                       sofar = (*x->state) (c, buf, Statelen - 2);
                        rv = readstr(offset, p, n, buf);
                        kfree(buf);
                        return rv;
index 67f7781..a619c3f 100644 (file)
@@ -141,7 +141,7 @@ extern char *icmpconnect(struct conv *c, char **argv, int argc)
 
 extern int icmpstate(struct conv *c, char *state, int n)
 {
-       return snprintf(state, n, "%s qin %d qout %d",
+       return snprintf(state, n, "%s qin %d qout %d\n",
                                        "Datagram",
                                        c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
 }
index fedcd60..c29517f 100644 (file)
@@ -455,7 +455,7 @@ static int tcpstate(struct conv *c, char *state, int n)
        s = (Tcpctl *) (c->ptcl);
 
        return snprintf(state, n,
-                                       "%s qin %d qout %d srtt %d mdev %d cwin %lu swin %lu>>%d rwin %lu>>%d timer.start %llu timer.count %llu rerecv %d katimer.start %d katimer.count %d\n",
+                                       "%s qin %d qout %d srtt %d mdev %d cwin %u swin %u>>%d rwin %u>>%d timer.start %llu timer.count %llu rerecv %d katimer.start %d katimer.count %d\n",
                                        tcpstates[s->state],
                                        c->rq ? qlen(c->rq) : 0,
                                        c->wq ? qlen(c->wq) : 0,
index 10fa78b..a47231e 100644 (file)
@@ -136,7 +136,7 @@ static char *udpconnect(struct conv *c, char **argv, int argc)
 
 static int udpstate(struct conv *c, char *state, int n)
 {
-       return snprintf(state, n, "%s qin %d qout %d",
+       return snprintf(state, n, "%s qin %d qout %d\n",
                                        c->inuse ? "Open" : "Closed",
                                        c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
 }