diff --git a/usr.bin/systat/Makefile b/usr.bin/systat/Makefile index 0f4a40e7b3cc..1bbaae6b4608 100644 --- a/usr.bin/systat/Makefile +++ b/usr.bin/systat/Makefile @@ -8,7 +8,5 @@ SRCS= cmds.c cmdtab.c devs.c fetch.c iostat.c keyboard.c main.c \ vmstat.c DPADD= ${LIBCURSES} ${LIBM} ${LIBKVM} ${LIBDEVSTAT} LDADD= -lcurses -lm -lkvm -ldevstat -BINGRP= kmem -BINMODE=2555 .include diff --git a/usr.bin/systat/extern.h b/usr.bin/systat/extern.h index d6e3887e6e74..b3a01290522c 100644 --- a/usr.bin/systat/extern.h +++ b/usr.bin/systat/extern.h @@ -31,6 +31,7 @@ * SUCH DAMAGE. * * @(#)extern.h 8.1 (Berkeley) 6/6/93 + * $FreeBSD$ */ #include @@ -67,6 +68,8 @@ extern int num_selected; extern int num_selections; extern long select_generation; +extern struct nlist namelist[]; + int checkhost __P((struct inpcb *)); int checkport __P((struct inpcb *)); void closeiostat __P((WINDOW *)); @@ -97,6 +100,7 @@ void fetchnetstat __P((void)); void fetchpigs __P((void)); void fetchswap __P((void)); void fetchtcp __P((void)); +void getsysctl __P((char *, void *, size_t)); int initicmp __P((void)); int initip __P((void)); int initiostat __P((void)); @@ -145,3 +149,4 @@ void showswap __P((void)); void showtcp __P((void)); void status __P((void)); void suspend __P((int)); +char *sysctl_dynread __P((char *, size_t *)); diff --git a/usr.bin/systat/fetch.c b/usr.bin/systat/fetch.c index ff69ac5e821e..94ef6190476d 100644 --- a/usr.bin/systat/fetch.c +++ b/usr.bin/systat/fetch.c @@ -29,6 +29,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ #ifndef lint @@ -36,6 +38,13 @@ static char sccsid[] = "@(#)fetch.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #include +#include + +#include +#include +#include +#include + #include "systat.h" #include "extern.h" @@ -46,9 +55,94 @@ kvm_ckread(a, b, l) { if (kvm_read(kd, (u_long)a, b, l) != l) { if (verbose) - error("error reading kmem at %x\n", a); + error("error reading kmem at %x", a); return (0); } else return (1); } + +void getsysctl(name, ptr, len) + char *name; + void *ptr; + size_t len; +{ + int err; + size_t nlen = len; + if ((err = sysctlbyname(name, ptr, &nlen, NULL, 0)) != 0) { + error("sysctl(%s...) failed: %s", name, + strerror(errno)); + } + if (nlen != len) { + error("sysctl(%s...) expected %d, got %d", name, + len, nlen); + } +} + +/* + * Read sysctl data with variable size. Try some times (with increasing + * buffers), fail if still too small. + * This is needed sysctls with possibly raplidly increasing data sizes, + * but imposes little overhead in the case of constant sizes. + * Returns NULL on error, or a pointer to freshly malloc()'ed memory that holds + * the requested data. + * If szp is not NULL, the size of the returned data will be written into *szp. + */ + +/* Some defines: Number of tries. */ +#define SD_NTRIES 10 +/* Percent of over-allocation (initial) */ +#define SD_MARGIN 10 +/* + * Factor for over-allocation in percent (the margin is increased by this on + * any failed try). + */ +#define SD_FACTOR 50 +/* Maximum supported MIB depth */ +#define SD_MAXMIB 16 + +char * +sysctl_dynread(n, szp) + char *n; + size_t *szp; +{ + char *rv = NULL; + int mib[SD_MAXMIB]; + size_t mibsz = SD_MAXMIB; + size_t mrg = SD_MARGIN; + size_t sz; + int i; + + /* cache the MIB */ + if (sysctlnametomib(n, mib, &mibsz) == -1) { + if (errno == ENOMEM) { + error("XXX: SD_MAXMIB too small, please bump!"); + } + return NULL; + } + for (i = 0; i < SD_NTRIES; i++) { + /* get needed buffer size */ + if (sysctl(mib, mibsz, NULL, &sz, NULL, 0) == -1) + break; + sz += sz * mrg / 100; + if ((rv = (char *)malloc(sz)) == NULL) { + error("Out of memory!"); + return NULL; + } + if (sysctl(mib, mibsz, rv, &sz, NULL, 0) == -1) { + free(rv); + rv = NULL; + if (errno == ENOMEM) { + mrg += mrg * SD_FACTOR / 100; + } else + break; + } else { + /* success */ + if (szp != NULL) + *szp = sz; + break; + } + } + + return rv; +} diff --git a/usr.bin/systat/iostat.c b/usr.bin/systat/iostat.c index 20d90d045703..44e3b0cfa898 100644 --- a/usr.bin/systat/iostat.c +++ b/usr.bin/systat/iostat.c @@ -66,6 +66,7 @@ static char sccsid[] = "@(#)iostat.c 8.1 (Berkeley) 6/6/93"; #include #include +#include #include #include @@ -110,7 +111,7 @@ closeiostat(w) int initiostat() { - if (num_devices = getnumdevs() < 0) + if ((num_devices = getnumdevs()) < 0) return(0); cur.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c index 52bb1e579671..5678e41391e2 100644 --- a/usr.bin/systat/main.c +++ b/usr.bin/systat/main.c @@ -47,6 +47,7 @@ static const char rcsid[] = #include #include +#include #include #include @@ -74,6 +75,7 @@ char *namp; char hostname[MAXHOSTNAMELEN]; WINDOW *wnd; int CMDLINE; +int use_kvm = 1; static WINDOW *wload; /* one line window for load average */ @@ -82,7 +84,7 @@ main(argc, argv) int argc; char **argv; { - char errbuf[80]; + char errbuf[80], dummy; size_t size; int err; @@ -107,9 +109,29 @@ main(argc, argv) argc--, argv++; } kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); + if (kd != NULL) { + /* + * Try to actually read something, we may be in a jail, and + * have /dev/null opened as /dev/mem. + */ + if (kvm_nlist(kd, namelist) != 0 || namelist[0].n_value == 0 || + kvm_read(kd, namelist[0].n_value, &dummy, sizeof(dummy)) != + sizeof(dummy)) { + kvm_close(kd); + kd = NULL; + } + } if (kd == NULL) { - error("%s", errbuf); - exit(1); + /* + * Maybe we are lacking permissions? Retry, this time with bogus + * devices. We can now use sysctl only. + */ + use_kvm = 0; + kd = kvm_openfiles("/dev/null", "/dev/null", "/dev/null", O_RDONLY, errbuf); + if (kd == NULL) { + error("%s", errbuf); + exit(1); + } } signal(SIGINT, die); signal(SIGQUIT, die); diff --git a/usr.bin/systat/netcmds.c b/usr.bin/systat/netcmds.c index b5d0422143a8..80a321325654 100644 --- a/usr.bin/systat/netcmds.c +++ b/usr.bin/systat/netcmds.c @@ -253,7 +253,7 @@ showports() for (p = ports; p < ports+nports; p++) { sp = getservbyport(p->port, - protos == TCP|UDP ? 0 : protos == TCP ? "tcp" : "udp"); + protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp"); if (!p->onoff) addch('!'); if (sp) diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c index 85ee610edbad..723f85398cff 100644 --- a/usr.bin/systat/netstat.c +++ b/usr.bin/systat/netstat.c @@ -60,6 +60,7 @@ static const char rcsid[] = #include #include #include +#include #define TCPSTATES #include #include @@ -76,7 +77,11 @@ static const char rcsid[] = #include "systat.h" #include "extern.h" -static void enter __P((struct inpcb *, struct socket *, int, char *)); +static struct netinfo *enter __P((struct inpcb *, int, char *)); +static void enter_kvm __P((struct inpcb *, struct socket *, int, char *)); +static void enter_sysctl __P((struct inpcb *, struct xsocket *, int, char *)); +static void fetchnetstat_kvm __P((void)); +static void fetchnetstat_sysctl __P((void)); static char *inetname __P((struct in_addr)); static void inetprint __P((struct in_addr *, int, char *)); @@ -113,7 +118,6 @@ TAILQ_HEAD(netinfohead, netinfo) netcb = TAILQ_HEAD_INITIALIZER(netcb); static int aflag = 0; static int nflag = 0; static int lastrow = 1; -static void enter(), inetprint(); static char *inetname(); void @@ -136,31 +140,37 @@ closenetstat(w) } } -static struct nlist namelist[] = { +static char *miblist[] = { + "net.inet.tcp.pcblist", + "net.inet.udp.pcblist" +}; + +struct nlist namelist[] = { #define X_TCB 0 - { "_tcb" }, + { "tcb" }, #define X_UDB 1 - { "_udb" }, + { "udb" }, { "" }, }; int initnetstat() { - if (kvm_nlist(kd, namelist)) { - nlisterr(namelist); - return(0); - } - if (namelist[X_TCB].n_value == 0) { - error("No symbols in namelist"); - return(0); - } protos = TCP|UDP; return(1); } void fetchnetstat() +{ + if (use_kvm) + fetchnetstat_kvm(); + else + fetchnetstat_sysctl(); +} + +static void +fetchnetstat_kvm() { register struct inpcb *next; register struct netinfo *p; @@ -201,9 +211,9 @@ again: KREAD(inpcb.inp_socket, &sockb, sizeof (sockb)); if (istcp) { KREAD(inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); - enter(&inpcb, &sockb, tcpcb.t_state, "tcp"); + enter_kvm(&inpcb, &sockb, tcpcb.t_state, "tcp"); } else - enter(&inpcb, &sockb, 0, "udp"); + enter_kvm(&inpcb, &sockb, 0, "udp"); } if (istcp && (protos&UDP)) { istcp = 0; @@ -213,7 +223,84 @@ again: } static void -enter(inp, so, state, proto) +fetchnetstat_sysctl() +{ + register struct netinfo *p; + int idx; + struct xinpgen *inpg; + char *cur, *end; + struct inpcb *inpcb; + struct xinpcb *xip; + struct xtcpcb *xtp; + int plen; + size_t lsz; + + TAILQ_FOREACH(p, &netcb, chain) + p->ni_seen = 0; + if (protos&TCP) { + idx = 0; + } else if (protos&UDP) { + idx = 1; + } else { + error("No protocols to display"); + return; + } + + for (;idx < 2; idx++) { + if (idx == 1 && !(protos&UDP)) + break; + inpg = (struct xinpgen *)sysctl_dynread(miblist[idx], &lsz); + if (inpg == NULL) { + error("sysctl(%s...) failed", miblist[idx]); + continue; + } + /* + * We currently do no require a consistent pcb list. + * Try to be robust in case of struct size changes + */ + cur = ((char *)inpg) + inpg->xig_len; + /* There is also a trailing struct xinpgen */ + end = ((char *)inpg) + lsz - inpg->xig_len; + if (end <= cur) { + free(inpg); + continue; + } + if (idx == 0) { /* TCP */ + xtp = (struct xtcpcb *)cur; + plen = xtp->xt_len; + } else { + xip = (struct xinpcb *)cur; + plen = xip->xi_len; + } + while (cur + plen <= end) { + if (idx == 0) { /* TCP */ + xtp = (struct xtcpcb *)cur; + inpcb = &xtp->xt_inp; + } else { + xip = (struct xinpcb *)cur; + inpcb = &xip->xi_inp; + } + cur += plen; + + if (!aflag && inet_lnaof(inpcb->inp_laddr) == + INADDR_ANY) + continue; + if (nhosts && !checkhost(inpcb)) + continue; + if (nports && !checkport(inpcb)) + continue; + if (idx == 0) /* TCP */ + enter_sysctl(inpcb, &xtp->xt_socket, + xtp->xt_tp.t_state, "tcp"); + else /* UDP */ + enter_sysctl(inpcb, &xip->xi_socket, 0, "udp"); + } + free(inpg); + } +} + +static void +enter_kvm(inp, so, state, proto) register struct inpcb *inp; register struct socket *so; int state; @@ -221,6 +308,36 @@ enter(inp, so, state, proto) { register struct netinfo *p; + if ((p = enter(inp, state, proto)) != NULL) { + p->ni_rcvcc = so->so_rcv.sb_cc; + p->ni_sndcc = so->so_snd.sb_cc; + } +} + +static void +enter_sysctl(inp, so, state, proto) + register struct inpcb *inp; + register struct xsocket *so; + int state; + char *proto; +{ + register struct netinfo *p; + + if ((p = enter(inp, state, proto)) != NULL) { + p->ni_rcvcc = so->so_rcv.sb_cc; + p->ni_sndcc = so->so_snd.sb_cc; + } +} + + +static struct netinfo * +enter(inp, state, proto) + register struct inpcb *inp; + int state; + char *proto; +{ + register struct netinfo *p; + /* * Only take exact matches, any sockets with * previously unbound addresses will be deleted @@ -241,7 +358,7 @@ enter(inp, so, state, proto) if (p == NULL) { if ((p = malloc(sizeof(*p))) == NULL) { error("Out of memory"); - return; + return NULL; } TAILQ_INSERT_HEAD(&netcb, p, chain); p->ni_line = -1; @@ -252,10 +369,9 @@ enter(inp, so, state, proto) p->ni_proto = proto; p->ni_flags = NIF_LACHG|NIF_FACHG; } - p->ni_rcvcc = so->so_rcv.sb_cc; - p->ni_sndcc = so->so_snd.sb_cc; p->ni_state = state; p->ni_seen = 1; + return p; } /* column locations */ @@ -270,7 +386,7 @@ enter(inp, so, state, proto) void labelnetstat() { - if (namelist[X_TCB].n_type == 0) + if (use_kvm && namelist[X_TCB].n_type == 0) return; wmove(wnd, 0, 0); wclrtobot(wnd); mvwaddstr(wnd, 0, LADDR, "Local Address"); @@ -291,9 +407,12 @@ shownetstat() * away and adjust the position of connections * below to reflect the deleted line. */ - TAILQ_FOREACH(p, &netcb, chain) { - if (p->ni_line == -1 || p->ni_seen) + p = TAILQ_FIRST(&netcb); + while (p != NULL) { + if (p->ni_line == -1 || p->ni_seen) { + p = TAILQ_NEXT(p, chain); continue; + } wmove(wnd, p->ni_line, 0); wdeleteln(wnd); TAILQ_FOREACH(q, &netcb, chain) if (q != p && q->ni_line > p->ni_line) { @@ -302,7 +421,7 @@ shownetstat() q->ni_flags |= NIF_LACHG|NIF_FACHG; } lastrow--; - q = TAILQ_PREV(p, netinfohead, chain); + q = TAILQ_NEXT(p, chain); TAILQ_REMOVE(&netcb, p, chain); free(p); p = q; diff --git a/usr.bin/systat/swap.c b/usr.bin/systat/swap.c index e3168927aaff..f4b3267ed501 100644 --- a/usr.bin/systat/swap.c +++ b/usr.bin/systat/swap.c @@ -92,11 +92,8 @@ closeswap(w) int initswap() { - int i; char msgbuf[BUFSIZ]; - char *cp; static int once = 0; - u_long ptr; struct kvm_swap dummy; if (once) @@ -124,7 +121,7 @@ fetchswap() void labelswap() { - char *header, *p; + char *header; int row, i; fetchswap(); diff --git a/usr.bin/systat/systat.h b/usr.bin/systat/systat.h index d8045d8fecff..d4ea835df94e 100644 --- a/usr.bin/systat/systat.h +++ b/usr.bin/systat/systat.h @@ -49,12 +49,20 @@ struct cmdtab { char c_flags; /* see below */ }; +/* + * If we are started with privileges, use a kmem interface for netstat handling, + * otherwise use sysctl. + * In case of many open sockets, the sysctl handling might become slow. + */ +extern int use_kvm; + #define CF_INIT 0x1 /* been initialized */ #define CF_LOADAV 0x2 /* display w/ load average */ #define TCP 0x1 #define UDP 0x2 +#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) #define KREAD(addr, buf, len) kvm_ckread((addr), (buf), (len)) #define NVAL(indx) namelist[(indx)].n_value #define NPTR(indx) (void *)NVAL((indx)) diff --git a/usr.bin/systat/vmstat.c b/usr.bin/systat/vmstat.c index f9bdc17c0099..7779de326b2b 100644 --- a/usr.bin/systat/vmstat.c +++ b/usr.bin/systat/vmstat.c @@ -74,7 +74,43 @@ static const char rcsid[] = static struct Info { long time[CPUSTATES]; - struct vmmeter Cnt; + u_int v_swtch; /* context switches */ + u_int v_trap; /* calls to trap */ + u_int v_syscall; /* calls to syscall() */ + u_int v_intr; /* device interrupts */ + u_int v_soft; /* software interrupts */ + /* + * Virtual memory activity. + */ + u_int v_vm_faults; /* number of address memory faults */ + u_int v_cow_faults; /* number of copy-on-writes */ + u_int v_zfod; /* pages zero filled on demand */ + u_int v_ozfod; /* optimized zero fill pages */ + u_int v_swapin; /* swap pager pageins */ + u_int v_swapout; /* swap pager pageouts */ + u_int v_swappgsin; /* swap pager pages paged in */ + u_int v_swappgsout; /* swap pager pages paged out */ + u_int v_vnodein; /* vnode pager pageins */ + u_int v_vnodeout; /* vnode pager pageouts */ + u_int v_vnodepgsin; /* vnode_pager pages paged in */ + u_int v_vnodepgsout; /* vnode pager pages paged out */ + u_int v_intrans; /* intransit blocking page faults */ + u_int v_reactivated; /* number of pages reactivated from free list */ + u_int v_pdwakeups; /* number of times daemon has awaken from sleep */ + u_int v_pdpages; /* number of pages analyzed by daemon */ + + u_int v_dfree; /* pages freed by daemon */ + u_int v_pfree; /* pages freed by exiting processes */ + u_int v_tfree; /* total pages freed */ + /* + * Distribution of page usages. + */ + u_int v_page_size; /* page size in bytes */ + u_int v_free_count; /* number of pages free */ + u_int v_wire_count; /* number of pages wired down */ + u_int v_active_count; /* number of pages active */ + u_int v_inactive_count; /* number of pages inactive */ + u_int v_cache_count; /* number of pages on buffer cache queue */ struct vmtotal Total; struct nchstats nchstats; long nchcount; @@ -88,8 +124,6 @@ static struct Info { struct statinfo cur, last, run; -#define cnt s.Cnt -#define oldcnt s1.Cnt #define total s.Total #define nchtotal s.nchstats #define oldnchtotal s1.nchstats @@ -142,21 +176,6 @@ closekre(w) wrefresh(w); } - -static struct nlist namelist[] = { -#define X_CNT 0 - { "_cnt" }, -#define X_INTRNAMES 1 - { "_intrnames" }, -#define X_EINTRNAMES 2 - { "_eintrnames" }, -#define X_INTRCNT 3 - { "_intrcnt" }, -#define X_EINTRCNT 4 - { "_eintrcnt" }, - { "" }, -}; - /* * These constants define where the major pieces are laid out */ @@ -191,18 +210,7 @@ initkre() char *intrnamebuf, *cp; int i; - if (namelist[0].n_type == 0) { - if (kvm_nlist(kd, namelist)) { - nlisterr(namelist); - return(0); - } - if (namelist[0].n_type == 0) { - error("No namelist"); - return(0); - } - } - - if (num_devices = getnumdevs() < 0) { + if ((num_devices = getnumdevs()) < 0) { warnx("%s", devstat_errbuf); return(0); } @@ -218,14 +226,13 @@ initkre() return(0); if (nintr == 0) { - nintr = (namelist[X_EINTRCNT].n_value - - namelist[X_INTRCNT].n_value) / sizeof (long); + GETSYSCTL("hw.nintr", nintr); intrloc = calloc(nintr, sizeof (long)); intrname = calloc(nintr, sizeof (long)); - intrnamebuf = malloc(namelist[X_EINTRNAMES].n_value - - namelist[X_INTRNAMES].n_value); - if (intrnamebuf == 0 || intrname == 0 || intrloc == 0) { - error("Out of memory\n"); + intrnamebuf = sysctl_dynread("hw.intrnames", NULL); + if (intrnamebuf == NULL || intrname == NULL || + intrloc == NULL) { + error("Out of memory"); if (intrnamebuf) free(intrnamebuf); if (intrname) @@ -235,8 +242,6 @@ initkre() nintr = 0; return(0); } - NREAD(X_INTRNAMES, intrnamebuf, NVAL(X_EINTRNAMES) - - NVAL(X_INTRNAMES)); for (cp = intrnamebuf, i = 0; i < nintr; i++) { intrname[i] = cp; cp += strlen(cp) + 1; @@ -453,7 +458,7 @@ showkre() putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0); putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0); mvaddstr(STATROW, STATCOL + 53, buf); -#define pgtokb(pg) ((pg) * cnt.v_page_size / 1024) +#define pgtokb(pg) ((pg) * s.v_page_size / 1024) putint(pgtokb(total.t_arm), MEMROW + 2, MEMCOL + 3, 8); putint(pgtokb(total.t_armshr), MEMROW + 2, MEMCOL + 11, 8); putint(pgtokb(total.t_avm), MEMROW + 2, MEMCOL + 19, 9); @@ -469,34 +474,34 @@ showkre() putint(total.t_sl, PROCSROW + 1, PROCSCOL + 12, 3); putint(total.t_sw, PROCSROW + 1, PROCSCOL + 15, 3); if (extended_vm_stats == 0) { - PUTRATE(Cnt.v_zfod, VMSTATROW + 0, VMSTATCOL + 4, 5); + PUTRATE(v_zfod, VMSTATROW + 0, VMSTATCOL + 4, 5); } - PUTRATE(Cnt.v_cow_faults, VMSTATROW + 1, VMSTATCOL + 3, 6); - putint(pgtokb(cnt.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9); - putint(pgtokb(cnt.v_active_count), VMSTATROW + 3, VMSTATCOL, 9); - putint(pgtokb(cnt.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9); - putint(pgtokb(cnt.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9); - putint(pgtokb(cnt.v_free_count), VMSTATROW + 6, VMSTATCOL, 9); - PUTRATE(Cnt.v_dfree, VMSTATROW + 7, VMSTATCOL, 9); - PUTRATE(Cnt.v_pfree, VMSTATROW + 8, VMSTATCOL, 9); - PUTRATE(Cnt.v_reactivated, VMSTATROW + 9, VMSTATCOL, 9); - PUTRATE(Cnt.v_pdwakeups, VMSTATROW + 10, VMSTATCOL, 9); - PUTRATE(Cnt.v_pdpages, VMSTATROW + 11, VMSTATCOL, 9); - PUTRATE(Cnt.v_intrans, VMSTATROW + 12, VMSTATCOL, 9); + PUTRATE(v_cow_faults, VMSTATROW + 1, VMSTATCOL + 3, 6); + putint(pgtokb(s.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9); + putint(pgtokb(s.v_active_count), VMSTATROW + 3, VMSTATCOL, 9); + putint(pgtokb(s.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9); + putint(pgtokb(s.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9); + putint(pgtokb(s.v_free_count), VMSTATROW + 6, VMSTATCOL, 9); + PUTRATE(v_dfree, VMSTATROW + 7, VMSTATCOL, 9); + PUTRATE(v_pfree, VMSTATROW + 8, VMSTATCOL, 9); + PUTRATE(v_reactivated, VMSTATROW + 9, VMSTATCOL, 9); + PUTRATE(v_pdwakeups, VMSTATROW + 10, VMSTATCOL, 9); + PUTRATE(v_pdpages, VMSTATROW + 11, VMSTATCOL, 9); + PUTRATE(v_intrans, VMSTATROW + 12, VMSTATCOL, 9); if (extended_vm_stats) { - PUTRATE(Cnt.v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9); - PUTRATE(Cnt.v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9); + PUTRATE(v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9); + PUTRATE(v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9); putint( - ((s.Cnt.v_ozfod < s.Cnt.v_zfod) ? - s.Cnt.v_ozfod * 100 / s.Cnt.v_zfod : + ((s.v_ozfod < s.v_zfod) ? + s.v_ozfod * 100 / s.v_zfod : 0 ), VMSTATROW + 13, VMSTATCOL - 16, 9 ); - PUTRATE(Cnt.v_tfree, VMSTATROW + 14, VMSTATCOL - 16, 9); + PUTRATE(v_tfree, VMSTATROW + 14, VMSTATCOL - 16, 9); } putint(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9); @@ -504,20 +509,20 @@ showkre() putint(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9); putint(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9); putint(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9); - PUTRATE(Cnt.v_vnodein, PAGEROW + 2, PAGECOL + 5, 5); - PUTRATE(Cnt.v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5); - PUTRATE(Cnt.v_swapin, PAGEROW + 2, PAGECOL + 17, 5); - PUTRATE(Cnt.v_swapout, PAGEROW + 2, PAGECOL + 22, 5); - PUTRATE(Cnt.v_vnodepgsin, PAGEROW + 3, PAGECOL + 5, 5); - PUTRATE(Cnt.v_vnodepgsout, PAGEROW + 3, PAGECOL + 10, 5); - PUTRATE(Cnt.v_swappgsin, PAGEROW + 3, PAGECOL + 17, 5); - PUTRATE(Cnt.v_swappgsout, PAGEROW + 3, PAGECOL + 22, 5); - PUTRATE(Cnt.v_swtch, GENSTATROW + 1, GENSTATCOL, 5); - PUTRATE(Cnt.v_trap, GENSTATROW + 1, GENSTATCOL + 5, 5); - PUTRATE(Cnt.v_syscall, GENSTATROW + 1, GENSTATCOL + 10, 5); - PUTRATE(Cnt.v_intr, GENSTATROW + 1, GENSTATCOL + 15, 5); - PUTRATE(Cnt.v_soft, GENSTATROW + 1, GENSTATCOL + 20, 5); - PUTRATE(Cnt.v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 5); + PUTRATE(v_vnodein, PAGEROW + 2, PAGECOL + 5, 5); + PUTRATE(v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5); + PUTRATE(v_swapin, PAGEROW + 2, PAGECOL + 17, 5); + PUTRATE(v_swapout, PAGEROW + 2, PAGECOL + 22, 5); + PUTRATE(v_vnodepgsin, PAGEROW + 3, PAGECOL + 5, 5); + PUTRATE(v_vnodepgsout, PAGEROW + 3, PAGECOL + 10, 5); + PUTRATE(v_swappgsin, PAGEROW + 3, PAGECOL + 17, 5); + PUTRATE(v_swappgsout, PAGEROW + 3, PAGECOL + 22, 5); + PUTRATE(v_swtch, GENSTATROW + 1, GENSTATCOL, 5); + PUTRATE(v_trap, GENSTATROW + 1, GENSTATCOL + 5, 5); + PUTRATE(v_syscall, GENSTATROW + 1, GENSTATCOL + 10, 5); + PUTRATE(v_intr, GENSTATROW + 1, GENSTATCOL + 15, 5); + PUTRATE(v_soft, GENSTATROW + 1, GENSTATCOL + 20, 5); + PUTRATE(v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 5); mvprintw(DISKROW, DISKCOL + 5, " "); for (i = 0, c = 0; i < num_devices && c < MAXDRIVES; i++) if (dev_select[i].selected) { @@ -721,51 +726,48 @@ getinfo(s, st) enum state st; { struct devinfo *tmp_dinfo; - size_t len, size; - int mib[2], err; + size_t size; + int mib[2]; - len = sizeof(s->time); - err = sysctlbyname("kern.cp_time", &s->time, &len, NULL, 0); - if (err || len != sizeof(s->time)) - perror("kern.cp_time"); - - len = sizeof(cur.cp_time); - err = sysctlbyname("kern.cp_time", &cur.cp_time, &len, NULL, 0); - if (err || len != sizeof(cur.cp_time)) - perror("kern.cp_time"); - - NREAD(X_CNT, &s->Cnt, sizeof s->Cnt); - - len = sizeof(s->bufspace); - err = sysctlbyname("vfs.bufspace", &s->bufspace, &len, NULL, 0); - if (err || len != sizeof(s->bufspace)) - perror("vfs.bufspace"); - - len = sizeof(s->desiredvnodes); - err = sysctlbyname("kern.maxvnodes", &s->desiredvnodes, &len, NULL, 0); - if (err || len != sizeof(s->desiredvnodes)) - perror("kern.maxvnodes"); - - len = sizeof(s->numvnodes); - err = sysctlbyname("debug.numvnodes", &s->numvnodes, &len, NULL, 0); - if (err || len != sizeof(s->numvnodes)) - perror("debug.numvnodes"); - - len = sizeof(s->freevnodes); - err = sysctlbyname("debug.freevnodes", &s->freevnodes, &len, NULL, 0); - if (err || len != sizeof(s->freevnodes)) - perror("debug.freevnodes"); - - len = sizeof(s->nchstats); - err = sysctlbyname("vfs.cache.nchstats", &s->nchstats, &len, NULL, 0); - if (err || len != sizeof(s->nchstats)) - perror("vfs.cache.nchstats"); - - NREAD(X_INTRCNT, s->intrcnt, nintr * LONG); - - len = sizeof(s->numdirtybuffers); - err = sysctlbyname("vfs.numdirtybuffers", &s->numdirtybuffers, &len, - NULL, 0); + GETSYSCTL("kern.cp_time", s->time); + GETSYSCTL("kern.cp_time", cur.cp_time); + GETSYSCTL("vm.stats.sys.v_swtch", s->v_swtch); + GETSYSCTL("vm.stats.sys.v_trap", s->v_trap); + GETSYSCTL("vm.stats.sys.v_syscall", s->v_syscall); + GETSYSCTL("vm.stats.sys.v_intr", s->v_intr); + GETSYSCTL("vm.stats.sys.v_soft", s->v_soft); + GETSYSCTL("vm.stats.vm.v_vm_faults", s->v_vm_faults); + GETSYSCTL("vm.stats.vm.v_cow_faults", s->v_cow_faults); + GETSYSCTL("vm.stats.vm.v_zfod", s->v_zfod); + GETSYSCTL("vm.stats.vm.v_ozfod", s->v_ozfod); + GETSYSCTL("vm.stats.vm.v_swapin", s->v_swapin); + GETSYSCTL("vm.stats.vm.v_swapout", s->v_swapout); + GETSYSCTL("vm.stats.vm.v_swappgsin", s->v_swappgsin); + GETSYSCTL("vm.stats.vm.v_swappgsout", s->v_swappgsout); + GETSYSCTL("vm.stats.vm.v_vnodein", s->v_vnodein); + GETSYSCTL("vm.stats.vm.v_vnodeout", s->v_vnodeout); + GETSYSCTL("vm.stats.vm.v_vnodepgsin", s->v_vnodepgsin); + GETSYSCTL("vm.stats.vm.v_vnodepgsout", s->v_vnodepgsout); + GETSYSCTL("vm.stats.vm.v_intrans", s->v_intrans); + GETSYSCTL("vm.stats.vm.v_reactivated", s->v_reactivated); + GETSYSCTL("vm.stats.vm.v_pdwakeups", s->v_pdwakeups); + GETSYSCTL("vm.stats.vm.v_pdpages", s->v_pdpages); + GETSYSCTL("vm.stats.vm.v_dfree", s->v_dfree); + GETSYSCTL("vm.stats.vm.v_pfree", s->v_pfree); + GETSYSCTL("vm.stats.vm.v_tfree", s->v_tfree); + GETSYSCTL("vm.stats.vm.v_page_size", s->v_page_size); + GETSYSCTL("vm.stats.vm.v_free_count", s->v_free_count); + GETSYSCTL("vm.stats.vm.v_wire_count", s->v_wire_count); + GETSYSCTL("vm.stats.vm.v_active_count", s->v_active_count); + GETSYSCTL("vm.stats.vm.v_inactive_count", s->v_inactive_count); + GETSYSCTL("vm.stats.vm.v_cache_count", s->v_cache_count); + GETSYSCTL("vfs.bufspace", s->bufspace); + GETSYSCTL("kern.maxvnodes", s->desiredvnodes); + GETSYSCTL("debug.numvnodes", s->numvnodes); + GETSYSCTL("debug.freevnodes", s->freevnodes); + GETSYSCTL("vfs.cache.nchstats", s->nchstats); + GETSYSCTL("vfs.numdirtybuffers", s->numdirtybuffers); + getsysctl("hw.intrcnt", s->intrcnt, nintr * LONG); size = sizeof(s->Total); mib[0] = CTL_VM;