Update the kernel to count the number of mbufs and clusters

(all types) used per socket buffer.

Add support to netstat to print out all of the socket buffer
statistics.

Update the netstat manual page to describe the new -x flag
which gives the extended output.

Reviewed by:	rwatson, julian
This commit is contained in:
George V. Neville-Neil 2008-05-15 20:18:44 +00:00
parent 90356491d7
commit 49f287f8c5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=179027
6 changed files with 81 additions and 13 deletions

View File

@ -1027,6 +1027,8 @@ sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb)
xsb->sb_cc = sb->sb_cc;
xsb->sb_hiwat = sb->sb_hiwat;
xsb->sb_mbcnt = sb->sb_mbcnt;
xsb->sb_mcnt = sb->sb_mcnt;
xsb->sb_ccnt = sb->sb_ccnt;
xsb->sb_mbmax = sb->sb_mbmax;
xsb->sb_lowat = sb->sb_lowat;
xsb->sb_flags = sb->sb_flags;

View File

@ -110,6 +110,8 @@ struct socket {
u_int sb_cc; /* (c/d) actual chars in buffer */
u_int sb_hiwat; /* (c/d) max actual char count */
u_int sb_mbcnt; /* (c/d) chars of mbufs used */
u_int sb_mcnt; /* (c/d) number of mbufs in buffer */
u_int sb_ccnt; /* (c/d) number of clusters in buffer */
u_int sb_mbmax; /* (c/d) max chars of mbufs to use */
u_int sb_ctl; /* (c/d) non-data chars in buffer */
int sb_lowat; /* (c/d) low water mark */
@ -259,6 +261,8 @@ struct xsocket {
u_int sb_cc;
u_int sb_hiwat;
u_int sb_mbcnt;
u_int sb_mcnt;
u_int sb_ccnt;
u_int sb_mbmax;
int sb_lowat;
int sb_timeo;
@ -320,8 +324,11 @@ struct xsocket {
if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
(sb)->sb_ctl += (m)->m_len; \
(sb)->sb_mbcnt += MSIZE; \
if ((m)->m_flags & M_EXT) \
(sb)->sb_mcnt += 1; \
if ((m)->m_flags & M_EXT) { \
(sb)->sb_mbcnt += (m)->m_ext.ext_size; \
(sb)->sb_ccnt += 1; \
} \
}
/* adjust counters in sb reflecting freeing of m */
@ -330,8 +337,11 @@ struct xsocket {
if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
(sb)->sb_ctl -= (m)->m_len; \
(sb)->sb_mbcnt -= MSIZE; \
if ((m)->m_flags & M_EXT) \
(sb)->sb_mcnt -= 1; \
if ((m)->m_flags & M_EXT) { \
(sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
(sb)->sb_ccnt -= 1; \
} \
if ((sb)->sb_sndptr == (m)) { \
(sb)->sb_sndptr = NULL; \
(sb)->sb_sndptroff = 0; \

View File

@ -142,6 +142,8 @@ sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb)
xsb->sb_cc = sb->sb_cc;
xsb->sb_hiwat = sb->sb_hiwat;
xsb->sb_mbcnt = sb->sb_mbcnt;
xsb->sb_mcnt = sb->sb_mcnt;
xsb->sb_ccnt = sb->sb_ccnt;
xsb->sb_mbmax = sb->sb_mbmax;
xsb->sb_lowat = sb->sb_lowat;
xsb->sb_flags = sb->sb_flags;
@ -405,13 +407,19 @@ protopr(u_long off, const char *name, int af1, int proto)
if (Lflag)
printf("%-5.5s %-14.14s %-22.22s\n",
"Proto", "Listen", "Local Address");
printf((Aflag && !Wflag) ?
"%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" :
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s",
"Proto", "Recv-Q", "Send-Q",
"Local Address", "Foreign Address");
if (xflag)
printf("%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %s\n",
"R-MBUF", "S-MBUF", "R-CLUS", "S-CLUS",
"R-HIWA", "S-HIWA", "R-LOWA", "S-LOWA",
"R-BCNT", "S-BCNT", "R-BMAX", "S-BMAX",
"(state)");
else
printf((Aflag && !Wflag) ?
"%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
"Proto", "Recv-Q", "Send-Q",
"Local Address", "Foreign Address",
"(state)");
printf("(state)\n");
first = 0;
}
if (Lflag && so->so_qlimit == 0)
@ -438,7 +446,8 @@ protopr(u_long off, const char *name, int af1, int proto)
so->so_incqlen, so->so_qlimit);
printf("%-14.14s ", buf1);
} else {
printf("%6u %6u ", so->so_rcv.sb_cc, so->so_snd.sb_cc);
printf("%6u %6u ",
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
if (numeric_port) {
if (inp->inp_vflag & INP_IPV4) {
@ -494,10 +503,29 @@ protopr(u_long off, const char *name, int af1, int proto)
} /* else nothing printed now */
#endif /* INET6 */
}
if (xflag) {
if (Lflag)
printf("%21s %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ",
" ",
so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt,
so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt,
so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat,
so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
else
printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ",
so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt,
so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt,
so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat,
so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
}
if (istcp && !Lflag) {
if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
printf("%d", tp->t_state);
else {
else {
printf("%s", tcpstates[tp->t_state]);
#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
/* Show T/TCP `hidden state' */
@ -505,7 +533,7 @@ protopr(u_long off, const char *name, int af1, int proto)
putchar('*');
#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
}
}
}
putchar('\n');
}
if (xig != oxig && xig->xig_gen != oxig->xig_gen) {

View File

@ -331,6 +331,7 @@ int rflag; /* show routing tables (or routing stats) */
int sflag; /* show protocol statistics */
int tflag; /* show i/f watchdog timers */
int Wflag; /* wide display */
int xflag; /* extra information, includes all socket buffer info */
int zflag; /* zero stats */
int interval; /* repeat interval for i/f stats */
@ -349,7 +350,7 @@ main(int argc, char *argv[])
af = AF_UNSPEC;
while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:rSstuWw:z")) != -1)
while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:rSstuWw:xz")) != -1)
switch(ch) {
case 'A':
Aflag = 1;
@ -456,6 +457,9 @@ main(int argc, char *argv[])
interval = atoi(optarg);
iflag = 1;
break;
case 'x':
xflag = 1;
break;
case 'z':
zflag = 1;
break;

View File

@ -49,7 +49,7 @@ depending on the options for the information presented.
.It Xo
.Bk -words
.Nm
.Op Fl AaLnSW
.Op Fl AaLnSWx
.Op Fl f Ar protocol_family | Fl p Ar protocol
.Op Fl M Ar core
.Op Fl N Ar system
@ -85,6 +85,9 @@ is also present,
show network addresses as numbers (as with
.Fl n )
but show ports symbolically.
If
.Fl x
is present display full socket buffer statistics for each internet socket.
.It Xo
.Bk -words
.Nm
@ -454,6 +457,26 @@ remotely on the interface.
.Pp
For more information about these flags, please refer to
.Xr bpf 4 .
.Pp
The
.Fl x
flag causes netstat to output all the information recorded about data
stored in the socket buffers. The fields are:
.Bl -column ".Li R-MBUF"
.It Li R-MBUF Ta Number of mbufs in the receive queue.
.It Li S-MBUF Ta Number of mbufs in the send queue.
.It Li R-CLUS Ta Number of clusters, of any type, in the recieve
queue.
.It Li S-CLUS Ta Number of clusters, of any type, in the send queue.
.It Li R-HIWA Ta Receive buffer high water mark, in bytes.
.It Li S-HIWA Ta Send buffer high water mark, in bytes.
.It Li R-LOWA Ta Receive buffer low water mark, in bytes.
.It Li S-LOWA Ta Send buffer low water mark, in bytes.
.It Li R-BCNT Ta Receive buffer byte count.
.It Li S-BCNT Ta Send buffer byte count.
.It Li R-BMAX Ta Maximum bytes that can be used in the receive buffer.
.It Li S-BMAX Ta Maximum bytes that can be used in the send buffer.
.El
.Sh SEE ALSO
.Xr fstat 1 ,
.Xr nfsstat 1 ,

View File

@ -51,6 +51,7 @@ extern int rflag; /* show routing tables (or routing stats) */
extern int sflag; /* show protocol statistics */
extern int tflag; /* show i/f watchdog timers */
extern int Wflag; /* wide display */
extern int xflag; /* extended display, includes all socket buffer info */
extern int zflag; /* zero stats */
extern int interval; /* repeat interval for i/f stats */