mbufs.c revision 84153
1/*-
2 * Copyright (c) 1980, 1992, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)mbufs.c	8.1 (Berkeley) 6/6/93";
36static const char rcsid[] =
37  "$FreeBSD: head/usr.bin/systat/mbufs.c 84153 2001-09-30 01:58:39Z bmilekic $";
38#endif /* not lint */
39
40#include <sys/param.h>
41#include <sys/types.h>
42#include <sys/mbuf.h>
43#include <sys/sysctl.h>
44
45#include <errno.h>
46#include <stdlib.h>
47#include <string.h>
48#include <paths.h>
49#include "systat.h"
50#include "extern.h"
51
52static struct mbpstat **mbpstat;
53static struct mbstat *mbstat;
54static int num_objs;
55static long *m_mbtypes;
56static short nmbtypes;
57#define	GENLST	(num_objs - 1)
58
59static struct mtnames {
60	short mt_type;
61	char *mt_name;
62} mtnames[] = {
63	{ MT_DATA, 	"data"},
64	{ MT_HEADER,	"headers"},
65	{ MT_SONAME,	"socknames"},
66	{ MT_FTABLE,	"frags"},
67	{ MT_CONTROL,	"control"},
68	{ MT_OOBDATA,	"oobdata"}
69};
70#define	NNAMES	(sizeof (mtnames) / sizeof (mtnames[0]))
71
72WINDOW *
73openmbufs()
74{
75	return (subwin(stdscr, LINES-5-1, 0, 5, 0));
76}
77
78void
79closembufs(w)
80	WINDOW *w;
81{
82	if (w == NULL)
83		return;
84	wclear(w);
85	wrefresh(w);
86	delwin(w);
87}
88
89void
90labelmbufs()
91{
92	wmove(wnd, 0, 0); wclrtoeol(wnd);
93	mvwaddstr(wnd, 0, 10,
94	    "/0   /5   /10  /15  /20  /25  /30  /35  /40  /45  /50  /55  /60");
95}
96
97void
98showmbufs()
99{
100	int i, j, max, index;
101	u_long totfree;
102	char buf[10];
103	char *mtname;
104
105	totfree = mbpstat[GENLST]->mb_mbfree;
106	for (i = 1; i < nmbtypes; i++)
107		m_mbtypes[i] += mbpstat[GENLST]->mb_mbtypes[i];
108	for (i = 0; i < GENLST; i++) {
109		if (mbpstat[i]->mb_active == 0)
110			continue;
111		totfree += mbpstat[i]->mb_mbfree;
112		for (j = 1; j < nmbtypes; j++)
113			m_mbtypes[j] += mbpstat[i]->mb_mbtypes[j];
114	}
115
116	/*
117	 * Print totals for different mbuf types.
118	 */
119	for (j = 0; j < wnd->_maxy; j++) {
120		max = 0, index = -1;
121		for (i = 0; i < wnd->_maxy; i++) {
122			if (i == MT_NOTMBUF)
123				continue;
124			if (i >= nmbtypes)
125				break;
126			if (m_mbtypes[i] > max) {
127				max = m_mbtypes[i];
128				index = i;
129			}
130		}
131		if (max == 0)
132			break;
133
134		mtname = NULL;
135		for (i = 0; i < NNAMES; i++)
136			if (mtnames[i].mt_type == index)
137				mtname = mtnames[i].mt_name;
138		if (mtname == NULL)
139			mvwprintw(wnd, 1+j, 0, "%10d", index);
140		else
141			mvwprintw(wnd, 1+j, 0, "%-10.10s", mtname);
142		wmove(wnd, 1 + j, 10);
143		if (max > 60) {
144			snprintf(buf, sizeof(buf), " %d", max);
145			max = 60;
146			while (max--)
147				waddch(wnd, 'X');
148			waddstr(wnd, buf);
149		} else
150			while (max--)
151				waddch(wnd, 'X');
152		wclrtoeol(wnd);
153		m_mbtypes[index] = 0;
154	}
155
156	/*
157	 * Print total number of free mbufs.
158	 */
159	if (totfree > 0) {
160		mvwprintw(wnd, 1+j, 0, "%-10.10s", "free");
161		if (totfree > 60) {
162			snprintf(buf, sizeof(buf), " %lu", totfree);
163			totfree = 60;
164			while(totfree--)
165				waddch(wnd, 'X');
166			waddstr(wnd, buf);
167		} else {
168			while(totfree--)
169				waddch(wnd, 'X');
170		}
171		wclrtoeol(wnd);
172		j++;
173	}
174	wmove(wnd, 1+j, 0); wclrtobot(wnd);
175}
176
177int
178initmbufs()
179{
180	int i;
181	size_t len;
182
183	len = sizeof *mbstat;
184	if ((mbstat = malloc(len)) == NULL) {
185		error("malloc mbstat failed");
186		return 0;
187	}
188	if (sysctlbyname("kern.ipc.mbstat", mbstat, &len, NULL, 0) < 0) {
189		error("sysctl retrieving mbstat");
190		return 0;
191	}
192	nmbtypes = mbstat->m_numtypes;
193	if ((m_mbtypes = calloc(nmbtypes, sizeof(long *))) == NULL) {
194		error("calloc m_mbtypes failed");
195		return 0;
196	}
197
198	if (sysctlbyname("kern.ipc.mb_statpcpu", NULL, &len, NULL, 0) < 0) {
199		error("sysctl getting mbpstat total size failed");
200		return 0;
201	}
202	num_objs = (int)(len / sizeof(struct mbpstat));
203	if ((mbpstat = calloc(num_objs, sizeof(struct mbpstat *))) == NULL) {
204		error("calloc mbpstat pointers failed");
205		return 0;
206	}
207	if ((mbpstat[0] = calloc(num_objs, sizeof(struct mbpstat))) == NULL) {
208		error("calloc mbpstat structures failed");
209		return 0;
210	}
211
212	for (i = 0; i < num_objs; i++)
213		mbpstat[i] = mbpstat[0] + i;
214
215	return 1;
216}
217
218void
219fetchmbufs()
220{
221	size_t len;
222
223	len = num_objs * sizeof(struct mbpstat);
224	if (sysctlbyname("kern.ipc.mb_statpcpu", mbpstat[0], &len, NULL, 0) < 0)
225		printw("sysctl: mbpstat: %s", strerror(errno));
226}
227