Wed Dec 26 01:47:37 2018 UTC ()
Extend "systat vm" output to provide better insight about buffercache and
document it.

From Greg A. Woods in PR bin/36542


(sevan)
diff -r1.28 -r1.29 src/usr.bin/systat/bufcache.c
diff -r1.25 -r1.26 src/usr.bin/systat/cmdtab.c
diff -r1.53 -r1.54 src/usr.bin/systat/main.c
diff -r1.48 -r1.49 src/usr.bin/systat/systat.1
diff -r1.11 -r1.12 src/usr.bin/systat/systat.h
diff -r1.82 -r1.83 src/usr.bin/systat/vmstat.c

cvs diff -r1.28 -r1.29 src/usr.bin/systat/bufcache.c (switch to unified diff)

--- src/usr.bin/systat/bufcache.c 2017/06/09 00:13:29 1.28
+++ src/usr.bin/systat/bufcache.c 2018/12/26 01:47:37 1.29
@@ -1,444 +1,444 @@ @@ -1,444 +1,444 @@
1/* $NetBSD: bufcache.c,v 1.28 2017/06/09 00:13:29 chs Exp $ */ 1/* $NetBSD: bufcache.c,v 1.29 2018/12/26 01:47:37 sevan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Simon Burge. 8 * by Simon Burge.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__RCSID("$NetBSD: bufcache.c,v 1.28 2017/06/09 00:13:29 chs Exp $"); 34__RCSID("$NetBSD: bufcache.c,v 1.29 2018/12/26 01:47:37 sevan Exp $");
35#endif /* not lint */ 35#endif /* not lint */
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/buf.h> 38#include <sys/buf.h>
39#define __EXPOSE_MOUNT 39#define __EXPOSE_MOUNT
40#include <sys/mount.h> 40#include <sys/mount.h>
41#include <sys/sysctl.h> 41#include <sys/sysctl.h>
42#include <sys/vnode.h> 42#include <sys/vnode.h>
43 43
44#include <uvm/uvm_extern.h> 44#include <uvm/uvm_extern.h>
45 45
46#include <err.h> 46#include <err.h>
47#include <errno.h> 47#include <errno.h>
48#include <inttypes.h> 48#include <inttypes.h>
49#include <math.h> 49#include <math.h>
50#include <stdlib.h> 50#include <stdlib.h>
51#include <string.h> 51#include <string.h>
52#include <unistd.h> 52#include <unistd.h>
53#include <stdbool.h> 53#include <stdbool.h>
54 54
55#include <miscfs/specfs/specdev.h> 55#include <miscfs/specfs/specdev.h>
56 56
57#include "systat.h" 57#include "systat.h"
58#include "extern.h" 58#include "extern.h"
59 59
60#define VCACHE_SIZE 50 60#define VCACHE_SIZE 50
61#define PAGEINFO_ROWS 5 61#define PAGEINFO_ROWS 5
62 62
63struct vcache { 63struct vcache {
64 int vc_age; 64 int vc_age;
65 struct vnode *vc_addr; 65 struct vnode *vc_addr;
66 struct vnode vc_node; 66 struct vnode vc_node;
67}; 67};
68 68
69struct ml_entry { 69struct ml_entry {
70 u_int ml_count; 70 u_int ml_count;
71 u_long ml_size; 71 u_long ml_size;
72 u_long ml_valid; 72 u_long ml_valid;
73 struct mount *ml_addr; 73 struct mount *ml_addr;
74 LIST_ENTRY(ml_entry) ml_entries; 74 LIST_ENTRY(ml_entry) ml_entries;
75 struct mount ml_mount; 75 struct mount ml_mount;
76}; 76};
77 77
78static struct vcache vcache[VCACHE_SIZE]; 78static struct vcache vcache[VCACHE_SIZE];
79static LIST_HEAD(mount_list, ml_entry) mount_list; 79static LIST_HEAD(mount_list, ml_entry) mount_list;
80 80
81static uint64_t bufmem; 81static uint64_t bufmem;
82static u_int nbuf, pgwidth, kbwidth; 82static u_int nbuf, pgwidth, kbwidth;
83static struct uvmexp_sysctl uvmexp; 83static struct uvmexp_sysctl uvmexp;
84 84
85static void vc_init(void); 85static void vc_init(void);
86static void ml_init(void); 86static void ml_init(void);
87static struct vnode *vc_lookup(struct vnode *); 87static struct vnode *vc_lookup(struct vnode *);
88static struct mount *ml_lookup(struct mount *, int, int); 88static struct mount *ml_lookup(struct mount *, int, int);
89static void fetchuvmexp(void); 89static void fetchuvmexp(void);
90 90
91 91
92WINDOW * 92WINDOW *
93openbufcache(void) 93openbufcache(void)
94{ 94{
95 95
96 return (subwin(stdscr, -1, 0, 5, 0)); 96 return (subwin(stdscr, -1, 0, 5, 0));
97} 97}
98 98
99void 99void
100closebufcache(WINDOW *w) 100closebufcache(WINDOW *w)
101{ 101{
102 102
103 if (w == NULL) 103 if (w == NULL)
104 return; 104 return;
105 wclear(w); 105 wclear(w);
106 wrefresh(w); 106 wrefresh(w);
107 delwin(w); 107 delwin(w);
108 ml_init(); /* Clear out mount list */ 108 ml_init(); /* Clear out mount list */
109} 109}
110 110
111void 111void
112labelbufcache(void) 112labelbufcache(void)
113{ 113{
114 int i; 114 int i;
115 115
116 for (i = 0; i <= PAGEINFO_ROWS; i++) { 116 for (i = 0; i <= PAGEINFO_ROWS; i++) {
117 wmove(wnd, i, 0); 117 wmove(wnd, i, 0);
118 wclrtoeol(wnd); 118 wclrtoeol(wnd);
119 } 119 }
120 mvwaddstr(wnd, PAGEINFO_ROWS + 1, 0, "File System Bufs used" 120 mvwaddstr(wnd, PAGEINFO_ROWS + 1, 0,
121 " % kB in use % Bufsize kB % Util %"); 121"File System Bufs used % kB in use % Bufsize kB % Util %");
122 wclrtoeol(wnd); 122 wclrtoeol(wnd);
123} 123}
124 124
125void 125void
126showbufcache(void) 126showbufcache(void)
127{ 127{
128 int tbuf, i, lastrow; 128 int tbuf, i, lastrow;
129 double tvalid, tsize; 129 double tvalid, tsize;
130 struct ml_entry *ml; 130 struct ml_entry *ml;
131 size_t len; 131 size_t len;
132 static int mib[] = { -1, 0 }; 132 static int mib[] = { -1, 0 };
133 133
134 if (mib[0] == -1) { 134 if (mib[0] == -1) {
135 len = __arraycount(mib); 135 len = __arraycount(mib);
136 if (sysctlnametomib("vm.bufmem", mib, &len) == -1) 136 if (sysctlnametomib("vm.bufmem", mib, &len) == -1)
137 error("can't get \"vm.bufmem\" mib: %s", 137 error("can't get \"vm.bufmem\" mib: %s",
138 strerror(errno)); 138 strerror(errno));
139 } 139 }
140 len = sizeof(bufmem); 140 len = sizeof(bufmem);
141 if (sysctl(mib, 2, &bufmem, &len, NULL, 0) == -1) 141 if (sysctl(mib, 2, &bufmem, &len, NULL, 0) == -1)
142 error("can't get \"vm.bufmem\": %s", strerror(errno)); 142 error("can't get \"vm.bufmem\": %s", strerror(errno));
143 143
144 mvwprintw(wnd, 0, 0, 144 mvwprintw(wnd, 0, 0,
145 " %*d metadata buffers using %*"PRIu64" kBytes of " 145 " %*d metadata buffers using %*"PRIu64" kBytes of "
146 "memory (%2.0f%%).", 146 "memory (%2.0f%%).",
147 pgwidth, nbuf, kbwidth, bufmem / 1024, 147 pgwidth, nbuf, kbwidth, bufmem / 1024,
148 ((bufmem * 100.0) + 0.5) / getpagesize() / uvmexp.npages); 148 ((bufmem * 100.0) + 0.5) / getpagesize() / uvmexp.npages);
149 wclrtoeol(wnd); 149 wclrtoeol(wnd);
150 mvwprintw(wnd, 1, 0, 150 mvwprintw(wnd, 1, 0,
151 " %*" PRIu64 " pages for cached file data using %*" 151 " %*" PRIu64 " pages for cached file data using %*"
152 PRIu64 " kBytes of memory (%2.0f%%).", 152 PRIu64 " kBytes of memory (%2.0f%%).",
153 pgwidth, uvmexp.filepages, 153 pgwidth, uvmexp.filepages,
154 kbwidth, uvmexp.filepages * getpagesize() / 1024, 154 kbwidth, uvmexp.filepages * getpagesize() / 1024,
155 (uvmexp.filepages * 100 + 0.5) / uvmexp.npages); 155 (uvmexp.filepages * 100 + 0.5) / uvmexp.npages);
156 wclrtoeol(wnd); 156 wclrtoeol(wnd);
157 mvwprintw(wnd, 2, 0, 157 mvwprintw(wnd, 2, 0,
158 " %*" PRIu64 " pages for executables using %*" 158 " %*" PRIu64 " pages for executables using %*"
159 PRIu64 " kBytes of memory (%2.0f%%).", 159 PRIu64 " kBytes of memory (%2.0f%%).",
160 pgwidth, uvmexp.execpages, 160 pgwidth, uvmexp.execpages,
161 kbwidth, uvmexp.execpages * getpagesize() / 1024, 161 kbwidth, uvmexp.execpages * getpagesize() / 1024,
162 (uvmexp.execpages * 100 + 0.5) / uvmexp.npages); 162 (uvmexp.execpages * 100 + 0.5) / uvmexp.npages);
163 wclrtoeol(wnd); 163 wclrtoeol(wnd);
164 mvwprintw(wnd, 3, 0, 164 mvwprintw(wnd, 3, 0,
165 " %*" PRIu64 " pages for anon (non-file) data %*" 165 " %*" PRIu64 " pages for anon (non-file) data %*"
166 PRIu64 " kBytes of memory (%2.0f%%).", 166 PRIu64 " kBytes of memory (%2.0f%%).",
167 pgwidth, uvmexp.anonpages, 167 pgwidth, uvmexp.anonpages,
168 kbwidth, uvmexp.anonpages * getpagesize() / 1024, 168 kbwidth, uvmexp.anonpages * getpagesize() / 1024,
169 (uvmexp.anonpages * 100 + 0.5) / uvmexp.npages); 169 (uvmexp.anonpages * 100 + 0.5) / uvmexp.npages);
170 wclrtoeol(wnd); 170 wclrtoeol(wnd);
171 mvwprintw(wnd, 4, 0, 171 mvwprintw(wnd, 4, 0,
172 " %*" PRIu64 " free pages %*" 172 " %*" PRIu64 " free pages %*"
173 PRIu64 " kBytes of memory (%2.0f%%).", 173 PRIu64 " kBytes of memory (%2.0f%%).",
174 pgwidth, uvmexp.free, 174 pgwidth, uvmexp.free,
175 kbwidth, uvmexp.free * getpagesize() / 1024, 175 kbwidth, uvmexp.free * getpagesize() / 1024,
176 (uvmexp.free * 100 + 0.5) / uvmexp.npages); 176 (uvmexp.free * 100 + 0.5) / uvmexp.npages);
177 wclrtoeol(wnd); 177 wclrtoeol(wnd);
178 178
179 if (nbuf == 0 || bufmem == 0) { 179 if (nbuf == 0 || bufmem == 0) {
180 wclrtobot(wnd); 180 wclrtobot(wnd);
181 return; 181 return;
182 } 182 }
183 183
184 tbuf = 0; 184 tbuf = 0;
185 tvalid = tsize = 0; 185 tvalid = tsize = 0;
186 lastrow = PAGEINFO_ROWS + 2; /* Leave room for header. */ 186 lastrow = PAGEINFO_ROWS + 2; /* Leave room for header. */
187 for (i = lastrow, ml = LIST_FIRST(&mount_list); ml != NULL; 187 for (i = lastrow, ml = LIST_FIRST(&mount_list); ml != NULL;
188 i++, ml = LIST_NEXT(ml, ml_entries)) { 188 i++, ml = LIST_NEXT(ml, ml_entries)) {
189 189
190 int cnt = ml->ml_count; 190 int cnt = ml->ml_count;
191 double v = ml->ml_valid; 191 double v = ml->ml_valid;
192 double s = ml->ml_size; 192 double s = ml->ml_size;
193 193
194 /* Display in window if enough room. */ 194 /* Display in window if enough room. */
195 if (i < getmaxy(wnd) - 2) { 195 if (i < getmaxy(wnd) - 2) {
196 mvwprintw(wnd, i, 0, "%-20.20s", ml->ml_addr == NULL ? 196 mvwprintw(wnd, i, 0, "%-20.20s", ml->ml_addr == NULL ?
197 "NULL" : ml->ml_mount.mnt_stat.f_mntonname); 197 "NULL" : ml->ml_mount.mnt_stat.f_mntonname);
198 wprintw(wnd, 198 wprintw(wnd,
199 " %6d %3d %8ld %3.0f %8ld %3.0f %3.0f", 199 " %6d %3d %8ld %3.0f %8ld %3.0f %3.0f",
200 cnt, (100 * cnt) / nbuf, 200 cnt, (100 * cnt) / nbuf,
201 (long)(v/1024), 100 * v / bufmem, 201 (long)(v/1024), 100 * v / bufmem,
202 (long)(s/1024), 100 * s / bufmem, 202 (long)(s/1024), 100 * s / bufmem,
203 100 * v / s); 203 100 * v / s);
204 wclrtoeol(wnd); 204 wclrtoeol(wnd);
205 lastrow = i; 205 lastrow = i;
206 } 206 }
207 207
208 /* Update statistics. */ 208 /* Update statistics. */
209 tbuf += cnt; 209 tbuf += cnt;
210 tvalid += v; 210 tvalid += v;
211 tsize += s; 211 tsize += s;
212 } 212 }
213 213
214 wclrtobot(wnd); 214 wclrtobot(wnd);
215 mvwprintw(wnd, lastrow + 2, 0, 215 mvwprintw(wnd, lastrow + 2, 0,
216 "%-20s %6d %3d %8ld %3.0f %8ld %3.0f %3.0f", 216 "%-20s %6d %3d %8ld %3.0f %8ld %3.0f %3.0f",
217 "Total:", tbuf, (100 * tbuf) / nbuf, 217 "Total:", tbuf, (100 * tbuf) / nbuf,
218 (long)(tvalid/1024), 100 * tvalid / bufmem, 218 (long)(tvalid/1024), 100 * tvalid / bufmem,
219 (long)(tsize/1024), 100 * tsize / bufmem, 219 (long)(tsize/1024), 100 * tsize / bufmem,
220 tsize != 0 ? ((100 * tvalid) / tsize) : 0); 220 tsize != 0 ? ((100 * tvalid) / tsize) : 0);
221} 221}
222 222
223int 223int
224initbufcache(void) 224initbufcache(void)
225{ 225{
226 fetchuvmexp(); 226 fetchuvmexp();
227 pgwidth = (int)(floor(log10((double)uvmexp.npages)) + 1); 227 pgwidth = (int)(floor(log10((double)uvmexp.npages)) + 1);
228 kbwidth = (int)(floor(log10(uvmexp.npages * getpagesize() / 1024.0)) + 228 kbwidth = (int)(floor(log10(uvmexp.npages * getpagesize() / 1024.0)) +
229 1); 229 1);
230 230
231 return(1); 231 return(1);
232} 232}
233 233
234static void 234static void
235fetchuvmexp(void) 235fetchuvmexp(void)
236{ 236{
237 int mib[2]; 237 int mib[2];
238 size_t size; 238 size_t size;
239 239
240 /* Re-read pages used for vnodes & executables */ 240 /* Re-read pages used for vnodes & executables */
241 size = sizeof(uvmexp); 241 size = sizeof(uvmexp);
242 mib[0] = CTL_VM; 242 mib[0] = CTL_VM;
243 mib[1] = VM_UVMEXP2; 243 mib[1] = VM_UVMEXP2;
244 if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { 244 if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
245 error("can't get uvmexp: %s\n", strerror(errno)); 245 error("can't get uvmexp: %s\n", strerror(errno));
246 memset(&uvmexp, 0, sizeof(uvmexp)); 246 memset(&uvmexp, 0, sizeof(uvmexp));
247 } 247 }
248} 248}
249 249
250void 250void
251fetchbufcache(void) 251fetchbufcache(void)
252{ 252{
253 int count; 253 int count;
254 struct buf_sysctl *bp, *buffers; 254 struct buf_sysctl *bp, *buffers;
255 struct vnode *vn; 255 struct vnode *vn;
256 struct ml_entry *ml; 256 struct ml_entry *ml;
257 int mib[6]; 257 int mib[6];
258 size_t size; 258 size_t size;
259 int extraslop = 0; 259 int extraslop = 0;
260 260
261 /* Re-read pages used for vnodes & executables */ 261 /* Re-read pages used for vnodes & executables */
262 fetchuvmexp(); 262 fetchuvmexp();
263 263
264 /* Initialise vnode cache and mount list. */ 264 /* Initialise vnode cache and mount list. */
265 vc_init(); 265 vc_init();
266 ml_init(); 266 ml_init();
267 267
268 /* Get metadata buffers */ 268 /* Get metadata buffers */
269 size = 0; 269 size = 0;
270 buffers = NULL; 270 buffers = NULL;
271 mib[0] = CTL_KERN; 271 mib[0] = CTL_KERN;
272 mib[1] = KERN_BUF; 272 mib[1] = KERN_BUF;
273 mib[2] = KERN_BUF_ALL; 273 mib[2] = KERN_BUF_ALL;
274 mib[3] = KERN_BUF_ALL; 274 mib[3] = KERN_BUF_ALL;
275 mib[4] = (int)sizeof(struct buf_sysctl); 275 mib[4] = (int)sizeof(struct buf_sysctl);
276 mib[5] = INT_MAX; /* we want them all */ 276 mib[5] = INT_MAX; /* we want them all */
277again: 277again:
278 if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) { 278 if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
279 error("can't get buffers size: %s\n", strerror(errno)); 279 error("can't get buffers size: %s\n", strerror(errno));
280 return; 280 return;
281 } 281 }
282 if (size == 0) 282 if (size == 0)
283 return; 283 return;
284 284
285 size += extraslop * sizeof(struct buf_sysctl); 285 size += extraslop * sizeof(struct buf_sysctl);
286 buffers = malloc(size); 286 buffers = malloc(size);
287 if (buffers == NULL) { 287 if (buffers == NULL) {
288 error("can't allocate buffers: %s\n", strerror(errno)); 288 error("can't allocate buffers: %s\n", strerror(errno));
289 return; 289 return;
290 } 290 }
291 if (sysctl(mib, 6, buffers, &size, NULL, 0) < 0) { 291 if (sysctl(mib, 6, buffers, &size, NULL, 0) < 0) {
292 free(buffers); 292 free(buffers);
293 if (extraslop == 0) { 293 if (extraslop == 0) {
294 extraslop = 100; 294 extraslop = 100;
295 goto again; 295 goto again;
296 } 296 }
297 error("can't get buffers: %s\n", strerror(errno)); 297 error("can't get buffers: %s\n", strerror(errno));
298 return; 298 return;
299 } 299 }
300 300
301 nbuf = size / sizeof(struct buf_sysctl); 301 nbuf = size / sizeof(struct buf_sysctl);
302 for (bp = buffers; bp < buffers + nbuf; bp++) { 302 for (bp = buffers; bp < buffers + nbuf; bp++) {
303 if (UINT64TOPTR(bp->b_vp) != NULL) { 303 if (UINT64TOPTR(bp->b_vp) != NULL) {
304 struct mount *mp; 304 struct mount *mp;
305 vn = vc_lookup(UINT64TOPTR(bp->b_vp)); 305 vn = vc_lookup(UINT64TOPTR(bp->b_vp));
306 if (vn == NULL) 306 if (vn == NULL)
307 break; 307 break;
308 308
309 mp = vn->v_mount; 309 mp = vn->v_mount;
310 /* 310 /*
311 * References to mounted-on vnodes should be 311 * References to mounted-on vnodes should be
312 * counted towards the mounted filesystem. 312 * counted towards the mounted filesystem.
313 */ 313 */
314 if (vn->v_type == VBLK && vn->v_specnode != NULL) { 314 if (vn->v_type == VBLK && vn->v_specnode != NULL) {
315 specnode_t sn; 315 specnode_t sn;
316 specdev_t sd; 316 specdev_t sd;
317 if (!KREAD(vn->v_specnode, &sn, sizeof(sn))) 317 if (!KREAD(vn->v_specnode, &sn, sizeof(sn)))
318 continue; 318 continue;
319 if (!KREAD(sn.sn_dev, &sd, sizeof(sd))) 319 if (!KREAD(sn.sn_dev, &sd, sizeof(sd)))
320 continue; 320 continue;
321 if (sd.sd_mountpoint) 321 if (sd.sd_mountpoint)
322 mp = sd.sd_mountpoint; 322 mp = sd.sd_mountpoint;
323 } 323 }
324 if (mp != NULL) 324 if (mp != NULL)
325 (void)ml_lookup(mp, bp->b_bufsize, 325 (void)ml_lookup(mp, bp->b_bufsize,
326 bp->b_bcount); 326 bp->b_bcount);
327 } 327 }
328 } 328 }
329 329
330 /* simple sort - there's not that many entries */ 330 /* simple sort - there's not that many entries */
331 do { 331 do {
332 if ((ml = LIST_FIRST(&mount_list)) == NULL || 332 if ((ml = LIST_FIRST(&mount_list)) == NULL ||
333 LIST_NEXT(ml, ml_entries) == NULL) 333 LIST_NEXT(ml, ml_entries) == NULL)
334 break; 334 break;
335 335
336 count = 0; 336 count = 0;
337 for (ml = LIST_FIRST(&mount_list); ml != NULL; 337 for (ml = LIST_FIRST(&mount_list); ml != NULL;
338 ml = LIST_NEXT(ml, ml_entries)) { 338 ml = LIST_NEXT(ml, ml_entries)) {
339 if (LIST_NEXT(ml, ml_entries) == NULL) 339 if (LIST_NEXT(ml, ml_entries) == NULL)
340 break; 340 break;
341 if (ml->ml_count < LIST_NEXT(ml, ml_entries)->ml_count) { 341 if (ml->ml_count < LIST_NEXT(ml, ml_entries)->ml_count) {
342 ml = LIST_NEXT(ml, ml_entries); 342 ml = LIST_NEXT(ml, ml_entries);
343 LIST_REMOVE(ml, ml_entries); 343 LIST_REMOVE(ml, ml_entries);
344 LIST_INSERT_HEAD(&mount_list, ml, ml_entries); 344 LIST_INSERT_HEAD(&mount_list, ml, ml_entries);
345 count++; 345 count++;
346 } 346 }
347 } 347 }
348 } while (count != 0); 348 } while (count != 0);
349 349
350 free(buffers); 350 free(buffers);
351} 351}
352 352
353static void 353static void
354vc_init(void) 354vc_init(void)
355{ 355{
356 int i; 356 int i;
357 357
358 /* vc_addr == NULL for unused cache entry. */ 358 /* vc_addr == NULL for unused cache entry. */
359 for (i = 0; i < VCACHE_SIZE; i++) 359 for (i = 0; i < VCACHE_SIZE; i++)
360 vcache[i].vc_addr = NULL; 360 vcache[i].vc_addr = NULL;
361} 361}
362 362
363static void 363static void
364ml_init(void) 364ml_init(void)
365{ 365{
366 struct ml_entry *ml; 366 struct ml_entry *ml;
367 367
368 /* Throw out the current mount list and start again. */ 368 /* Throw out the current mount list and start again. */
369 while ((ml = LIST_FIRST(&mount_list)) != NULL) { 369 while ((ml = LIST_FIRST(&mount_list)) != NULL) {
370 LIST_REMOVE(ml, ml_entries); 370 LIST_REMOVE(ml, ml_entries);
371 free(ml); 371 free(ml);
372 } 372 }
373} 373}
374 374
375 375
376static struct vnode * 376static struct vnode *
377vc_lookup(struct vnode *vaddr) 377vc_lookup(struct vnode *vaddr)
378{ 378{
379 struct vnode *ret; 379 struct vnode *ret;
380 size_t i, oldest; 380 size_t i, oldest;
381 381
382 ret = NULL; 382 ret = NULL;
383 oldest = 0; 383 oldest = 0;
384 for (i = 0; i < VCACHE_SIZE; i++) { 384 for (i = 0; i < VCACHE_SIZE; i++) {
385 if (vcache[i].vc_addr == NULL) 385 if (vcache[i].vc_addr == NULL)
386 break; 386 break;
387 vcache[i].vc_age++; 387 vcache[i].vc_age++;
388 if (vcache[i].vc_age < vcache[oldest].vc_age) 388 if (vcache[i].vc_age < vcache[oldest].vc_age)
389 oldest = i; 389 oldest = i;
390 if (vcache[i].vc_addr == vaddr) { 390 if (vcache[i].vc_addr == vaddr) {
391 vcache[i].vc_age = 0; 391 vcache[i].vc_age = 0;
392 ret = &vcache[i].vc_node; 392 ret = &vcache[i].vc_node;
393 } 393 }
394 } 394 }
395 395
396 /* Find an entry in the cache? */ 396 /* Find an entry in the cache? */
397 if (ret != NULL) 397 if (ret != NULL)
398 return(ret); 398 return(ret);
399 399
400 /* Go past the end of the cache? */ 400 /* Go past the end of the cache? */
401 if (i >= VCACHE_SIZE) 401 if (i >= VCACHE_SIZE)
402 i = oldest; 402 i = oldest;
403 403
404 /* Read in new vnode and reset age counter. */ 404 /* Read in new vnode and reset age counter. */
405 if (KREAD(vaddr, &vcache[i].vc_node, sizeof(struct vnode)) == 0) 405 if (KREAD(vaddr, &vcache[i].vc_node, sizeof(struct vnode)) == 0)
406 return NULL; 406 return NULL;
407 vcache[i].vc_addr = vaddr; 407 vcache[i].vc_addr = vaddr;
408 vcache[i].vc_age = 0; 408 vcache[i].vc_age = 0;
409 409
410 return(&vcache[i].vc_node); 410 return(&vcache[i].vc_node);
411} 411}
412 412
413static struct mount * 413static struct mount *
414ml_lookup(struct mount *maddr, int size, int valid) 414ml_lookup(struct mount *maddr, int size, int valid)
415{ 415{
416 struct ml_entry *ml; 416 struct ml_entry *ml;
417 417
418 for (ml = LIST_FIRST(&mount_list); ml != NULL; 418 for (ml = LIST_FIRST(&mount_list); ml != NULL;
419 ml = LIST_NEXT(ml, ml_entries)) 419 ml = LIST_NEXT(ml, ml_entries))
420 if (ml->ml_addr == maddr) { 420 if (ml->ml_addr == maddr) {
421 ml->ml_count++; 421 ml->ml_count++;
422 ml->ml_size += size; 422 ml->ml_size += size;
423 ml->ml_valid += valid; 423 ml->ml_valid += valid;
424 if (ml->ml_addr == NULL) 424 if (ml->ml_addr == NULL)
425 return(NULL); 425 return(NULL);
426 else 426 else
427 return(&ml->ml_mount); 427 return(&ml->ml_mount);
428 } 428 }
429 429
430 if ((ml = malloc(sizeof(struct ml_entry))) == NULL) { 430 if ((ml = malloc(sizeof(struct ml_entry))) == NULL) {
431 error("out of memory"); 431 error("out of memory");
432 die(0); 432 die(0);
433 } 433 }
434 LIST_INSERT_HEAD(&mount_list, ml, ml_entries); 434 LIST_INSERT_HEAD(&mount_list, ml, ml_entries);
435 ml->ml_count = 1; 435 ml->ml_count = 1;
436 ml->ml_size = size; 436 ml->ml_size = size;
437 ml->ml_valid = valid; 437 ml->ml_valid = valid;
438 ml->ml_addr = maddr; 438 ml->ml_addr = maddr;
439 if (maddr == NULL) 439 if (maddr == NULL)
440 return(NULL); 440 return(NULL);
441 441
442 KREAD(maddr, &ml->ml_mount, sizeof(struct mount)); 442 KREAD(maddr, &ml->ml_mount, sizeof(struct mount));
443 return(&ml->ml_mount); 443 return(&ml->ml_mount);
444} 444}

cvs diff -r1.25 -r1.26 src/usr.bin/systat/cmdtab.c (switch to unified diff)

--- src/usr.bin/systat/cmdtab.c 2016/08/02 15:56:09 1.25
+++ src/usr.bin/systat/cmdtab.c 2018/12/26 01:47:37 1.26
@@ -1,212 +1,213 @@ @@ -1,212 +1,213 @@
1/* $NetBSD: cmdtab.c,v 1.25 2016/08/02 15:56:09 scole Exp $ */ 1/* $NetBSD: cmdtab.c,v 1.26 2018/12/26 01:47:37 sevan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1980, 1992, 1993 4 * Copyright (c) 1980, 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93"; 35static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93";
36#endif 36#endif
37__RCSID("$NetBSD: cmdtab.c,v 1.25 2016/08/02 15:56:09 scole Exp $"); 37__RCSID("$NetBSD: cmdtab.c,v 1.26 2018/12/26 01:47:37 sevan Exp $");
38#endif /* not lint */ 38#endif /* not lint */
39 39
40#include "systat.h" 40#include "systat.h"
41#include "extern.h" 41#include "extern.h"
42 42
43/* 43/*
44 * NOTE: if one command is a substring of another, the shorter string 44 * NOTE: if one command is a substring of another, the shorter string
45 * MUST come first, or it will be shadowed by the longer 45 * MUST come first, or it will be shadowed by the longer
46 */ 46 */
47 47
48struct command global_commands[] = { 48struct command global_commands[] = {
49 { "help", global_help, "show help"}, 49 { "help", global_help, "show help"},
50 { "interval", global_interval, "set update interval"}, 50 { "interval", global_interval, "set update interval"},
51 { "load", global_load, "show system load averages"}, 51 { "load", global_load, "show system load averages"},
52 { "quit", global_quit, "exit systat"}, 52 { "quit", global_quit, "exit systat"},
53 { "start", global_interval, "restart updating display"}, 53 { "start", global_interval, "restart updating display"},
54 { "stop", global_stop, "stop updating display"}, 54 { "stop", global_stop, "stop updating display"},
 55 { "?", global_help, "show help"},
55 { .c_name = NULL } 56 { .c_name = NULL }
56}; 57};
57 58
58struct command df_commands[] = { 59struct command df_commands[] = {
59 { "all", df_all, "show all filesystems"}, 60 { "all", df_all, "show all filesystems"},
60 { "some", df_some, "show only some filesystems"}, 61 { "some", df_some, "show only some filesystems"},
61 { .c_name = NULL } 62 { .c_name = NULL }
62}; 63};
63  64
64struct command icmp_commands[] = { 65struct command icmp_commands[] = {
65 { "boot", icmp_boot, "show total stats since boot"}, 66 { "boot", icmp_boot, "show total stats since boot"},
66 { "run", icmp_run, "show running total stats"}, 67 { "run", icmp_run, "show running total stats"},
67 { "time", icmp_time, "show stats for each sample time"}, 68 { "time", icmp_time, "show stats for each sample time"},
68 { "zero", icmp_zero, "re-zero running totals"}, 69 { "zero", icmp_zero, "re-zero running totals"},
69 { .c_name = NULL } 70 { .c_name = NULL }
70}; 71};
71 72
72struct command ifstat_commands[] = { 73struct command ifstat_commands[] = {
73 { "scale", ifstat_scale, "modify scale of display"}, 74 { "scale", ifstat_scale, "modify scale of display"},
74 { "pps", ifstat_pps, "toggle packets per second display"}, 75 { "pps", ifstat_pps, "toggle packets per second display"},
75 { "match", ifstat_match, "display matching interfaces"}, 76 { "match", ifstat_match, "display matching interfaces"},
76 { .c_name = NULL } 77 { .c_name = NULL }
77}; 78};
78 79
79struct command iostat_commands[] = { 80struct command iostat_commands[] = {
80 { "bars", iostat_bars, "show io stats as a bar graph"}, 81 { "bars", iostat_bars, "show io stats as a bar graph"},
81 { "numbers", iostat_numbers, "show io stats numerically"}, 82 { "numbers", iostat_numbers, "show io stats numerically"},
82 { "secs", iostat_secs, "include time statistics"}, 83 { "secs", iostat_secs, "include time statistics"},
83 { "rw", iostat_rw, "show read/write disk stats"}, 84 { "rw", iostat_rw, "show read/write disk stats"},
84 { "all", iostat_all, "show combined disk stats"}, 85 { "all", iostat_all, "show combined disk stats"},
85 /* from disks.c */ 86 /* from disks.c */
86 { "display", disks_add, "add a disk to displayed disks"}, 87 { "display", disks_add, "add a disk to displayed disks"},
87 { "ignore", disks_remove, "remove a disk from displayed disks"}, 88 { "ignore", disks_remove, "remove a disk from displayed disks"},
88 { "drives", disks_drives, "list all disks/set disk list"}, 89 { "drives", disks_drives, "list all disks/set disk list"},
89 { .c_name = NULL } 90 { .c_name = NULL }
90}; 91};
91 92
92struct command ip_commands[] = { 93struct command ip_commands[] = {
93 { "boot", ip_boot, "show total stats since boot"}, 94 { "boot", ip_boot, "show total stats since boot"},
94 { "run", ip_run, "show running total stats"}, 95 { "run", ip_run, "show running total stats"},
95 { "time", ip_time, "show stats for each sample time"}, 96 { "time", ip_time, "show stats for each sample time"},
96 { "zero", ip_zero, "re-zero running totals"}, 97 { "zero", ip_zero, "re-zero running totals"},
97 { .c_name = NULL } 98 { .c_name = NULL }
98}; 99};
99 100
100#ifdef INET6 101#ifdef INET6
101struct command ip6_commands[] = { 102struct command ip6_commands[] = {
102 { "boot", ip6_boot, "show total stats since boot"}, 103 { "boot", ip6_boot, "show total stats since boot"},
103 { "run", ip6_run, "show running total stats"}, 104 { "run", ip6_run, "show running total stats"},
104 { "time", ip6_time, "show stats for each sample time"}, 105 { "time", ip6_time, "show stats for each sample time"},
105 { "zero", ip6_zero, "re-zero running totals"}, 106 { "zero", ip6_zero, "re-zero running totals"},
106 { .c_name = NULL } 107 { .c_name = NULL }
107}; 108};
108#endif 109#endif
109 110
110struct command netstat_commands[] = { 111struct command netstat_commands[] = {
111 { "all", netstat_all, "include server sockets"}, 112 { "all", netstat_all, "include server sockets"},
112 { "display", netstat_display, "show specified hosts or ports"}, 113 { "display", netstat_display, "show specified hosts or ports"},
113 { "ignore", netstat_ignore, "hide specified hosts or ports"}, 114 { "ignore", netstat_ignore, "hide specified hosts or ports"},
114 { "names", netstat_names, "show names instead of addresses"}, 115 { "names", netstat_names, "show names instead of addresses"},
115 { "numbers", netstat_numbers, "show addresses instead of names"}, 116 { "numbers", netstat_numbers, "show addresses instead of names"},
116 { "reset", netstat_reset, "return to default display"}, 117 { "reset", netstat_reset, "return to default display"},
117 { "show", netstat_show, "show current display/ignore settings"}, 118 { "show", netstat_show, "show current display/ignore settings"},
118 { "tcp", netstat_tcp, "show only tcp connections"}, 119 { "tcp", netstat_tcp, "show only tcp connections"},
119 { "udp", netstat_udp, "show only udp connections"}, 120 { "udp", netstat_udp, "show only udp connections"},
120 { .c_name = NULL } 121 { .c_name = NULL }
121}; 122};
122 123
123struct command ps_commands[] = { 124struct command ps_commands[] = {
124 { "user", ps_user, "limit displayed processes to a user"}, 125 { "user", ps_user, "limit displayed processes to a user"},
125 { .c_name = NULL } 126 { .c_name = NULL }
126}; 127};
127 128
128struct command tcp_commands[] = { 129struct command tcp_commands[] = {
129 { "boot", tcp_boot, "show total stats since boot"}, 130 { "boot", tcp_boot, "show total stats since boot"},
130 { "run", tcp_run, "show running total stats"}, 131 { "run", tcp_run, "show running total stats"},
131 { "time", tcp_time, "show stats for each sample time"}, 132 { "time", tcp_time, "show stats for each sample time"},
132 { "zero", tcp_zero, "re-zero running totals"}, 133 { "zero", tcp_zero, "re-zero running totals"},
133 { .c_name = NULL } 134 { .c_name = NULL }
134}; 135};
135 136
136struct command vmstat_commands[] = { 137struct command vmstat_commands[] = {
137 { "boot", vmstat_boot, "show total vm stats since boot"}, 138 { "boot", vmstat_boot, "show total vm stats since boot"},
138 { "run", vmstat_run, "show running total vm stats"}, 139 { "run", vmstat_run, "show running total vm stats"},
139 { "time", vmstat_time, "show vm stats for each sample time"}, 140 { "time", vmstat_time, "show vm stats for each sample time"},
140 { "zero", vmstat_zero, "re-zero running totals"}, 141 { "zero", vmstat_zero, "re-zero running totals"},
141 /* from disks.c */ 142 /* from disks.c */
142 { "display", disks_add, "add a disk to displayed disks"}, 143 { "display", disks_add, "add a disk to displayed disks"},
143 { "ignore", disks_remove, "remove a disk from displayed disks"}, 144 { "ignore", disks_remove, "remove a disk from displayed disks"},
144 { "drives", disks_drives, "list all disks/set disk list"}, 145 { "drives", disks_drives, "list all disks/set disk list"},
145 { .c_name = NULL } 146 { .c_name = NULL }
146}; 147};
147 148
148struct command syscall_commands[] = { 149struct command syscall_commands[] = {
149 { "boot", syscall_boot, "show total syscall stats since boot"}, 150 { "boot", syscall_boot, "show total syscall stats since boot"},
150 { "run", syscall_run, "show running total syscall stats"}, 151 { "run", syscall_run, "show running total syscall stats"},
151 { "time", syscall_time, "show syscall stats for each sample time"}, 152 { "time", syscall_time, "show syscall stats for each sample time"},
152 { "zero", syscall_zero, "re-zero running totals"}, 153 { "zero", syscall_zero, "re-zero running totals"},
153 { "sort", syscall_order, "sort by [name|count|syscall]"}, 154 { "sort", syscall_order, "sort by [name|count|syscall]"},
154 { "show", syscall_show, "show [count|time]"}, 155 { "show", syscall_show, "show [count|time]"},
155 { .c_name = NULL } 156 { .c_name = NULL }
156}; 157};
157 158
158struct mode modes[] = { 159struct mode modes[] = {
159 /* "pigs" is the default, it must be first. */ 160 /* "pigs" is the default, it must be first. */
160 { "pigs", showpigs, fetchpigs, labelpigs, 161 { "pigs", showpigs, fetchpigs, labelpigs,
161 initpigs, openpigs, closepigs, 0, 162 initpigs, openpigs, closepigs, 0,
162 CF_LOADAV }, 163 CF_LOADAV },
163 { "bufcache", showbufcache, fetchbufcache, labelbufcache, 164 { "bufcache", showbufcache, fetchbufcache, labelbufcache,
164 initbufcache, openbufcache, closebufcache, 0, 165 initbufcache, openbufcache, closebufcache, 0,
165 CF_LOADAV }, 166 CF_LOADAV },
166 { "df", showdf, fetchdf, labeldf, 167 { "df", showdf, fetchdf, labeldf,
167 initdf, opendf, closedf, df_commands, 168 initdf, opendf, closedf, df_commands,
168 CF_LOADAV }, 169 CF_LOADAV },
169 { "ifstat", showifstat, fetchifstat, labelifstat, 170 { "ifstat", showifstat, fetchifstat, labelifstat,
170 initifstat, openifstat, closeifstat, ifstat_commands, 171 initifstat, openifstat, closeifstat, ifstat_commands,
171 CF_LOADAV }, 172 CF_LOADAV },
172 { "inet.icmp", showicmp, fetchicmp, labelicmp, 173 { "inet.icmp", showicmp, fetchicmp, labelicmp,
173 initicmp, openicmp, closeicmp, icmp_commands, 174 initicmp, openicmp, closeicmp, icmp_commands,
174 CF_LOADAV }, 175 CF_LOADAV },
175 { "inet.ip", showip, fetchip, labelip, 176 { "inet.ip", showip, fetchip, labelip,
176 initip, openip, closeip, ip_commands, 177 initip, openip, closeip, ip_commands,
177 CF_LOADAV }, 178 CF_LOADAV },
178 { "inet.tcp", showtcp, fetchtcp, labeltcp, 179 { "inet.tcp", showtcp, fetchtcp, labeltcp,
179 inittcp, opentcp, closetcp, tcp_commands, 180 inittcp, opentcp, closetcp, tcp_commands,
180 CF_LOADAV }, 181 CF_LOADAV },
181 { "inet.tcpsyn",showtcpsyn, fetchtcp, labeltcpsyn, 182 { "inet.tcpsyn",showtcpsyn, fetchtcp, labeltcpsyn,
182 inittcp, opentcp, closetcp, tcp_commands, 183 inittcp, opentcp, closetcp, tcp_commands,
183 CF_LOADAV }, 184 CF_LOADAV },
184#ifdef INET6 185#ifdef INET6
185 { "inet6.ip6", showip6, fetchip6, labelip6, 186 { "inet6.ip6", showip6, fetchip6, labelip6,
186 initip6, openip6, closeip6, ip6_commands, 187 initip6, openip6, closeip6, ip6_commands,
187 CF_LOADAV }, 188 CF_LOADAV },
188#endif 189#endif
189 { "iostat", showiostat, fetchiostat, labeliostat, 190 { "iostat", showiostat, fetchiostat, labeliostat,
190 initiostat, openiostat, closeiostat, iostat_commands, 191 initiostat, openiostat, closeiostat, iostat_commands,
191 CF_LOADAV }, 192 CF_LOADAV },
192 { "mbufs", showmbufs, fetchmbufs, labelmbufs, 193 { "mbufs", showmbufs, fetchmbufs, labelmbufs,
193 initmbufs, openmbufs, closembufs, 0, 194 initmbufs, openmbufs, closembufs, 0,
194 CF_LOADAV }, 195 CF_LOADAV },
195 { "netstat", shownetstat, fetchnetstat, labelnetstat, 196 { "netstat", shownetstat, fetchnetstat, labelnetstat,
196 initnetstat, opennetstat, closenetstat, netstat_commands, 197 initnetstat, opennetstat, closenetstat, netstat_commands,
197 CF_LOADAV }, 198 CF_LOADAV },
198 { "ps", showps, fetchpigs, labelps, 199 { "ps", showps, fetchpigs, labelps,
199 initpigs, openpigs, closepigs, ps_commands, 200 initpigs, openpigs, closepigs, ps_commands,
200 CF_LOADAV }, 201 CF_LOADAV },
201 { "swap", showswap, fetchswap, labelswap, 202 { "swap", showswap, fetchswap, labelswap,
202 initswap, openswap, closeswap, 0, 203 initswap, openswap, closeswap, 0,
203 CF_LOADAV }, 204 CF_LOADAV },
204 { "vmstat", showvmstat, fetchvmstat, labelvmstat, 205 { "vmstat", showvmstat, fetchvmstat, labelvmstat,
205 initvmstat, openvmstat, closevmstat, vmstat_commands, 206 initvmstat, openvmstat, closevmstat, vmstat_commands,
206 0 }, 207 0 },
207 { "syscall", showsyscall, fetchsyscall, labelsyscall, 208 { "syscall", showsyscall, fetchsyscall, labelsyscall,
208 initsyscall, opensyscall, closesyscall, syscall_commands, 209 initsyscall, opensyscall, closesyscall, syscall_commands,
209 0 }, 210 0 },
210 { .c_name = NULL } 211 { .c_name = NULL }
211}; 212};
212struct mode *curmode = &modes[0]; 213struct mode *curmode = &modes[0];

cvs diff -r1.53 -r1.54 src/usr.bin/systat/main.c (switch to unified diff)

--- src/usr.bin/systat/main.c 2017/11/22 02:52:42 1.53
+++ src/usr.bin/systat/main.c 2018/12/26 01:47:37 1.54
@@ -1,417 +1,419 @@ @@ -1,417 +1,419 @@
1/* $NetBSD: main.c,v 1.53 2017/11/22 02:52:42 snj Exp $ */ 1/* $NetBSD: main.c,v 1.54 2018/12/26 01:47:37 sevan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1980, 1992, 1993 4 * Copyright (c) 1980, 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__COPYRIGHT("@(#) Copyright (c) 1980, 1992, 1993\ 34__COPYRIGHT("@(#) Copyright (c) 1980, 1992, 1993\
35 The Regents of the University of California. All rights reserved."); 35 The Regents of the University of California. All rights reserved.");
36#if 0 36#if 0
37static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; 37static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
38#endif 38#endif
39__RCSID("$NetBSD: main.c,v 1.53 2017/11/22 02:52:42 snj Exp $"); 39__RCSID("$NetBSD: main.c,v 1.54 2018/12/26 01:47:37 sevan Exp $");
40#endif /* not lint */ 40#endif /* not lint */
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/sysctl.h> 43#include <sys/sysctl.h>
44#include <sys/ioctl.h> 44#include <sys/ioctl.h>
45 45
46#include <ctype.h> 46#include <ctype.h>
47#include <err.h> 47#include <err.h>
48#include <errno.h> 48#include <errno.h>
49#include <limits.h> 49#include <limits.h>
50#include <signal.h> 50#include <signal.h>
51#include <stdarg.h> 51#include <stdarg.h>
52#include <stdio.h> 52#include <stdio.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <string.h> 54#include <string.h>
55#include <unistd.h> 55#include <unistd.h>
56#include <termios.h> 56#include <termios.h>
57 57
58#include "systat.h" 58#include "systat.h"
59#include "extern.h" 59#include "extern.h"
60 60
61static int dellave; 61static int dellave;
62 62
63kvm_t *kd; 63kvm_t *kd;
64char *memf = NULL; 64char *memf = NULL;
65char *nlistf = NULL; 65char *nlistf = NULL;
66sig_t sigtstpdfl; 66sig_t sigtstpdfl;
67double avenrun[3]; 67double avenrun[3];
68int col; 68int col;
69double naptime = 5; 69double naptime = 1;
70int verbose = 1; /* to report kvm read errs */ 70int verbose = 1; /* to report kvm read errs */
71int hz, stathz, maxslp; 71int hz, stathz, maxslp;
72char c; 72char c;
73char *namp; 73char *namp;
74char hostname[MAXHOSTNAMELEN + 1]; 74char hostname[MAXHOSTNAMELEN + 1];
75WINDOW *wnd; 75WINDOW *wnd;
76int CMDLINE; 76int CMDLINE;
77int turns = 2; /* stay how many refresh-turns in 'all' mode? */ 77int turns = 2; /* stay how many refresh-turns in 'all' mode? */
78int allflag; 78int allflag;
79int allcounter; 79int allcounter;
80sig_atomic_t needsredraw = 0; 80sig_atomic_t needsredraw = 0;
81 81
82static WINDOW *wload; /* one line window for load average */ 82static WINDOW *wload; /* one line window for load average */
83 83
84static void (*sv_stop_handler)(int); 84static void (*sv_stop_handler)(int);
85 85
86static void stop(int); 86static void stop(int);
87__dead static void usage(void); 87__dead static void usage(void);
88 88
89gid_t egid; /* XXX needed by initiostat() and initkre() */ 89gid_t egid; /* XXX needed by initiostat() and initkre() */
90 90
91int 91int
92main(int argc, char **argv) 92main(int argc, char **argv)
93{ 93{
94 int ch; 94 int ch;
95 char errbuf[_POSIX2_LINE_MAX]; 95 char errbuf[_POSIX2_LINE_MAX];
96 const char *all; 96 const char *all;
97 struct clockinfo clk; 97 struct clockinfo clk;
98 size_t len; 98 size_t len;
99 int bflag = 0; 99 int bflag = 0;
100 100
101 all = "all"; 101 all = "all";
102 egid = getegid(); 102 egid = getegid();
103 (void)setegid(getgid()); 103 (void)setegid(getgid());
104 104
105 while ((ch = getopt(argc, argv, "M:N:bnw:t:")) != -1) 105 while ((ch = getopt(argc, argv, "M:N:bnw:t:")) != -1)
106 switch(ch) { 106 switch(ch) {
107 case 'M': 107 case 'M':
108 memf = optarg; 108 memf = optarg;
109 break; 109 break;
110 case 'N': 110 case 'N':
111 nlistf = optarg; 111 nlistf = optarg;
112 break; 112 break;
113 case 'b': 113 case 'b':
114 bflag = !bflag; 114 bflag = !bflag;
115 break; 115 break;
116 case 'n': 116 case 'n':
117 nflag = !nflag; 117 nflag = !nflag;
118 break; 118 break;
119 case 't': 119 case 't':
120 if ((turns = atoi(optarg)) <= 0) 120 if ((turns = atoi(optarg)) <= 0)
121 errx(1, "turns <= 0."); 121 errx(1, "turns <= 0.");
122 break; 122 break;
123 case 'w': 123 case 'w':
124 if ((naptime = strtod(optarg, NULL)) <= 0) 124 if ((naptime = strtod(optarg, NULL)) <= 0)
125 errx(1, "interval <= 0."); 125 errx(1, "interval <= 0.");
126 break; 126 break;
127 case '?': 127 case '?':
128 default: 128 default:
129 usage(); 129 usage();
130 } 130 }
131 argc -= optind; 131 argc -= optind;
132 argv += optind; 132 argv += optind;
133 133
134 134
135 for ( ; argc > 0; argc--, argv++) { 135 for ( ; argc > 0; argc--, argv++) {
136 struct mode *p; 136 struct mode *p;
137 int modefound = 0; 137 int modefound = 0;
138 138
139 if (isdigit((unsigned char)argv[0][0])) { 139 if (isdigit((unsigned char)argv[0][0])) {
140 naptime = strtod(argv[0], NULL); 140 naptime = strtod(argv[0], NULL);
141 if (naptime <= 0) 141 if (naptime <= 0)
142 naptime = 5; 142 naptime = 5;
143 continue; 143 continue;
144 } 144 }
145 145
146 for (p = modes; p->c_name ; p++) { 146 for (p = modes; p->c_name ; p++) {
147 if (strstr(p->c_name, argv[0]) == p->c_name) { 147 if (strstr(p->c_name, argv[0]) == p->c_name) {
148 curmode = p; 148 curmode = p;
149 modefound++; 149 modefound++;
150 break; 150 break;
151 } 151 }
152 152
153 if (strstr(all, argv[0]) == all) { 153 if (strstr(all, argv[0]) == all) {
154 allcounter=0; 154 allcounter=0;
155 allflag=1; 155 allflag=1;
156 } 156 }
157 } 157 }
158 158
159 159
160 if (!modefound && !allflag) 160 if (!modefound && !allflag)
161 error("%s: Unknown command.", argv[0]); 161 error("%s: Unknown command.", argv[0]);
162 } 162 }
163 163
164 /* 164 /*
165 * Discard setgid privileges. If not the running kernel, we toss 165 * Discard setgid privileges. If not the running kernel, we toss
166 * them away totally so that bad guys can't print interesting stuff 166 * them away totally so that bad guys can't print interesting stuff
167 * from kernel memory, otherwise switch back to kmem for the 167 * from kernel memory, otherwise switch back to kmem for the
168 * duration of the kvm_openfiles() call. 168 * duration of the kvm_openfiles() call.
169 */ 169 */
170 if (nlistf != NULL || memf != NULL) 170 if (nlistf != NULL || memf != NULL)
171 (void)setgid(getgid()); 171 (void)setgid(getgid());
172 else 172 else
173 (void)setegid(egid); 173 (void)setegid(egid);
174 174
175 kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 175 kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
176 if (kd == NULL) { 176 if (kd == NULL)
177 error("%s", errbuf); 177 errx(1, "%s", errbuf);
178 exit(1); 
179 } 
180 178
181 /* Get rid of privs for now. */ 179 /* Get rid of privs for now. */
182 if (nlistf == NULL && memf == NULL) 180 if (nlistf == NULL && memf == NULL)
183 (void)setegid(getgid()); 181 (void)setegid(getgid());
184 182
185 signal(SIGINT, die); 183 signal(SIGINT, die);
186 signal(SIGQUIT, die); 184 signal(SIGQUIT, die);
187 signal(SIGTERM, die); 185 signal(SIGTERM, die);
188 sv_stop_handler = signal(SIGTSTP, stop); 186 sv_stop_handler = signal(SIGTSTP, stop);
189 187
190 /* 188 /*
191 * Initialize display. Load average appears in a one line 189 * Initialize display. Load average appears in a one line
192 * window of its own. Current command's display appears in 190 * window of its own. Current command's display appears in
193 * an overlapping sub-window of stdscr configured by the display 191 * an overlapping sub-window of stdscr configured by the display
194 * routines to minimize update work by curses. 192 * routines to minimize update work by curses.
195 */ 193 */
196 if (initscr() == NULL) 194 if (initscr() == NULL)
197 { 195 errx(1, "couldn't initialize screen");
198 warnx("couldn't initialize screen"); 
199 exit(0); 
200 } 
201 196
202 CMDLINE = LINES - 1; 197 CMDLINE = LINES - 1;
203 wnd = (*curmode->c_open)(); 198 wnd = (*curmode->c_open)();
204 if (wnd == NULL) { 199 if (wnd == NULL) {
 200 move(CMDLINE, 0);
 201 clrtoeol();
 202 refresh();
 203 endwin();
205 warnx("couldn't initialize display"); 204 warnx("couldn't initialize display");
206 die(0); 205 die(0);
207 } 206 }
208 wload = newwin(1, 0, 3, 20); 207 wload = newwin(1, 0, 3, 20);
209 if (wload == NULL) { 208 if (wload == NULL) {
 209 move(CMDLINE, 0);
 210 clrtoeol();
 211 refresh();
 212 endwin();
210 warnx("couldn't set up load average window"); 213 warnx("couldn't set up load average window");
211 die(0); 214 die(0);
212 } 215 }
213 gethostname(hostname, sizeof (hostname)); 216 gethostname(hostname, sizeof (hostname));
214 hostname[sizeof(hostname) - 1] = '\0'; 217 hostname[sizeof(hostname) - 1] = '\0';
215 218
216 len = sizeof(clk); 219 len = sizeof(clk);
217 if (sysctlbyname("kern.clockrate", &clk, &len, NULL, 0)) 220 if (sysctlbyname("kern.clockrate", &clk, &len, NULL, 0))
218 error("can't get \"kern.clockrate\": %s", strerror(errno)); 221 error("can't get \"kern.clockrate\": %s", strerror(errno));
219 hz = clk.hz; 222 hz = clk.hz;
220 stathz = clk.stathz; 223 stathz = clk.stathz;
221 224
222 len = sizeof(maxslp); 225 len = sizeof(maxslp);
223 if (sysctlbyname("vm.maxslp", &maxslp, &len, NULL, 0)) 226 if (sysctlbyname("vm.maxslp", &maxslp, &len, NULL, 0))
224 error("can't get \"vm.maxslp\": %s", strerror(errno)); 227 error("can't get \"vm.maxslp\": %s", strerror(errno));
225 228
226 (*curmode->c_init)(); 229 (*curmode->c_init)();
227 curmode->c_flags |= CF_INIT; 230 curmode->c_flags |= CF_INIT;
228 labels(); 231 labels();
229 232
230 dellave = 0.0; 233 dellave = 0.0;
231 234
232 display(0); 235 display(0);
233 if (!bflag) { 236 if (!bflag) {
234 noecho(); 237 noecho();
235 cbreak(); 238 cbreak();
236 keyboard(); 239 keyboard();
237 } else 240 } else
238 die(0); 241 die(0);
239 /*NOTREACHED*/ 242 /*NOTREACHED*/
240} 243}
241 244
242static void 245static void
243usage(void) 246usage(void)
244{ 247{
245 fprintf(stderr, "usage: systat [-bn] [-M core] [-N system] [-w wait] " 248 fprintf(stderr, "usage: systat [-bn] [-M core] [-N system] [-w wait] "
246 "[-t turns]\n\t\t[display] [refresh-interval]\n"); 249 "[-t turns]\n\t\t[display] [refresh-interval]\n");
247 exit(1); 250 exit(1);
248} 251}
249 252
250 253
251void 254void
252labels(void) 255labels(void)
253{ 256{
254 if (curmode->c_flags & CF_LOADAV) { 257 if (curmode->c_flags & CF_LOADAV) {
255 mvaddstr(2, 20, 258 mvaddstr(2, 20,
256 "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10"); 259 "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10");
257 mvaddstr(3, 5, "Load Average"); 260 mvaddstr(3, 5, "Load Average");
258 } 261 }
259 (*curmode->c_label)(); 262 (*curmode->c_label)();
260#ifdef notdef 263#ifdef notdef
261 mvprintw(21, 25, "CPU usage on %s", hostname); 264 mvprintw(21, 25, "CPU usage on %s", hostname);
262#endif 265#endif
263 refresh(); 266 refresh();
264} 267}
265 268
266void 269void
267display(int signo) 270display(int signo)
268{ 271{
269 static int skip; 272 static int skip;
270 int j; 273 int j;
271 struct mode *p; 274 struct mode *p;
272 int ms_delay; 275 int ms_delay;
273 276
274 if (signo == SIGALRM && skip-- > 0) 277 if (signo == SIGALRM && skip-- > 0)
275 /* Don't display on this timeout */ 278 /* Don't display on this timeout */
276 return; 279 return;
277 280
278 /* Get the load average over the last minute. */ 281 /* Get the load average over the last minute. */
279 (void)getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])); 282 (void)getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0]));
280 (*curmode->c_fetch)(); 283 (*curmode->c_fetch)();
281 if (curmode->c_flags & CF_LOADAV) { 284 if (curmode->c_flags & CF_LOADAV) {
282 j = 5.0*avenrun[0] + 0.5; 285 j = 5.0*avenrun[0] + 0.5;
283 dellave -= avenrun[0]; 286 dellave -= avenrun[0];
284 if (dellave >= 0.0) 287 if (dellave >= 0.0)
285 c = '<'; 288 c = '<';
286 else { 289 else {
287 c = '>'; 290 c = '>';
288 dellave = -dellave; 291 dellave = -dellave;
289 } 292 }
290 if (dellave < 0.1) 293 if (dellave < 0.1)
291 c = '|'; 294 c = '|';
292 dellave = avenrun[0]; 295 dellave = avenrun[0];
293 wmove(wload, 0, 0); 296 wmove(wload, 0, 0);
294 wclrtoeol(wload); 297 wclrtoeol(wload);
295 whline(wload, c, (j > 50) ? 50 : j); 298 whline(wload, c, (j > 50) ? 50 : j);
296 if (j > 50) 299 if (j > 50)
297 wprintw(wload, " %4.1f", avenrun[0]); 300 wprintw(wload, " %4.1f", avenrun[0]);
298 } 301 }
299 (*curmode->c_refresh)(); 302 (*curmode->c_refresh)();
300 if (curmode->c_flags & CF_LOADAV) 303 if (curmode->c_flags & CF_LOADAV)
301 wrefresh(wload); 304 wrefresh(wload);
302 wrefresh(wnd); 305 wrefresh(wnd);
303 move(CMDLINE, col); 306 move(CMDLINE, col);
304 refresh(); 307 refresh();
305  308
306 if (allflag && signo==SIGALRM) { 309 if (allflag && signo==SIGALRM) {
307 if (allcounter >= turns){ 310 if (allcounter >= turns){
308 p = curmode; 311 p = curmode;
309 p++; 312 p++;
310 if (p->c_name == NULL) 313 if (p->c_name == NULL)
311 p = modes; 314 p = modes;
312 switch_mode(p); 315 switch_mode(p);
313 allcounter=0; 316 allcounter=0;
314 } else 317 } else
315 allcounter++; 318 allcounter++;
316 } 319 }
317 320
318 /* curses timeout() uses VTIME, limited to 255 1/10th secs */ 321 /* curses timeout() uses VTIME, limited to 255 1/10th secs */
319 ms_delay = naptime * 1000; 322 ms_delay = naptime * 1000;
320 if (ms_delay < 25500) { 323 if (ms_delay < 25500) {
321 timeout(ms_delay); 324 timeout(ms_delay);
322 skip = 0; 325 skip = 0;
323 } else { 326 } else {
324 skip = ms_delay / 25500; 327 skip = ms_delay / 25500;
325 timeout(ms_delay / (skip + 1)); 328 timeout(ms_delay / (skip + 1));
326 } 329 }
327} 330}
328 331
329void 332void
330redraw(void) 333redraw(void)
331{ 334{
332 resizeterm(LINES, COLS); 335 resizeterm(LINES, COLS);
333 CMDLINE = LINES - 1; 336 CMDLINE = LINES - 1;
334 labels(); 337 labels();
335 338
336 display(0); 339 display(0);
337 needsredraw = 0; 340 needsredraw = 0;
338} 341}
339 342
340static void 343static void
341stop(int signo) 344stop(int signo)
342{ 345{
343 sigset_t set; 346 sigset_t set;
344 347
345 signal(SIGTSTP, sv_stop_handler); 348 signal(SIGTSTP, sv_stop_handler);
346 /* unblock SIGTSTP */ 349 /* unblock SIGTSTP */
347 sigemptyset(&set); 350 sigemptyset(&set);
348 sigaddset(&set, SIGTSTP); 351 sigaddset(&set, SIGTSTP);
349 sigprocmask(SIG_UNBLOCK, &set, NULL); 352 sigprocmask(SIG_UNBLOCK, &set, NULL);
350 /* stop ourselves */ 353 /* stop ourselves */
351 kill(0, SIGTSTP); 354 kill(0, SIGTSTP);
352 /* must have been restarted */ 355 /* must have been restarted */
353 signal(SIGTSTP, stop); 356 signal(SIGTSTP, stop);
354 needsredraw = signo; 357 needsredraw = signo;
355} 358}
356 359
357void 360void
358die(int signo) 361die(int signo)
359{ 362{
360 move(CMDLINE, 0); 363 move(CMDLINE, 0);
361 clrtoeol(); 364 clrtoeol();
362 refresh(); 365 refresh();
363 endwin(); 366 endwin();
364 exit(0); 367 exit(0);
365} 368}
366 369
367void 370void
368error(const char *fmt, ...) 371error(const char *fmt, ...)
369{ 372{
370 va_list ap; 373 va_list ap;
371 char buf[255]; 374 char buf[255];
372 int oy, ox; 375 int oy, ox;
373 376
374 va_start(ap, fmt); 377 va_start(ap, fmt);
375 378
376 if (wnd) { 379 if (wnd) {
377 getyx(stdscr, oy, ox); 380 getyx(stdscr, oy, ox);
378 (void) vsnprintf(buf, sizeof(buf), fmt, ap); 381 (void) vsnprintf(buf, sizeof(buf), fmt, ap);
379 clrtoeol(); 382 clrtoeol();
380 standout(); 383 standout();
381 mvaddstr(CMDLINE, 0, buf); 384 mvaddstr(CMDLINE, 0, buf);
382 standend(); 385 standend();
383 move(oy, ox); 386 move(oy, ox);
384 refresh(); 387 refresh();
385 } else { 388 } else {
386 (void) vfprintf(stderr, fmt, ap); 389 (void) vfprintf(stderr, fmt, ap);
387 fprintf(stderr, "\n"); 390 fprintf(stderr, "\n");
388 } 391 }
389 va_end(ap); 392 va_end(ap);
390} 393}
391 394
392void 395void
393clearerror(void) 396clearerror(void)
394{ 397{
395 398
396 error("%s", ""); 399 error("%s", "");
397} 400}
398 401
399void 402void
400nlisterr(struct nlist name_list[]) 403nlisterr(struct nlist name_list[])
401{ 404{
402 int i, n; 405 int i, n;
403 406
404 n = 0; 407 n = 0;
405 clear(); 408 clear();
406 mvprintw(2, 10, "systat: nlist: can't find following symbols:"); 409 mvprintw(2, 10, "systat: nlist: can't find following symbols:");
407 for (i = 0; 410 for (i = 0;
408 name_list[i].n_name != NULL && *name_list[i].n_name != '\0'; i++) 411 name_list[i].n_name != NULL && *name_list[i].n_name != '\0'; i++)
409 if (name_list[i].n_value == 0) 412 if (name_list[i].n_value == 0)
410 mvprintw(2 + ++n, 10, "%s", name_list[i].n_name); 413 mvprintw(2 + ++n, 10, "%s", name_list[i].n_name);
411 move(CMDLINE, 0); 414 move(CMDLINE, 0);
412 clrtoeol(); 415 clrtoeol();
413 refresh(); 416 refresh();
414 sleep(5); 
415 endwin(); 417 endwin();
416 exit(1); 418 exit(1);
417} 419}

cvs diff -r1.48 -r1.49 src/usr.bin/systat/systat.1 (switch to unified diff)

--- src/usr.bin/systat/systat.1 2017/07/03 21:34:21 1.48
+++ src/usr.bin/systat/systat.1 2018/12/26 01:47:37 1.49
@@ -1,635 +1,709 @@ @@ -1,635 +1,709 @@
1.\" $NetBSD: systat.1,v 1.48 2017/07/03 21:34:21 wiz Exp $ 1.\" $NetBSD: systat.1,v 1.49 2018/12/26 01:47:37 sevan Exp $
2.\" 2.\"
3.\" Copyright (c) 1985, 1990, 1993 3.\" Copyright (c) 1985, 1990, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission. 16.\" without specific prior written permission.
17.\" 17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
29.\" 29.\"
30.\" @(#)systat.1 8.2 (Berkeley) 12/30/93 30.\" @(#)systat.1 8.2 (Berkeley) 12/30/93
31.\" 31.\"
32.Dd November 16, 2016 32.Dd December 26, 2018
33.Dt SYSTAT 1 33.Dt SYSTAT 1
34.Os 34.Os
35.Sh NAME 35.Sh NAME
36.Nm systat 36.Nm systat
37.Nd display system statistics in a full-screen view 37.Nd display system statistics in a full-screen view
38.Sh SYNOPSIS 38.Sh SYNOPSIS
39.Nm 39.Nm
40.Op Fl bn 40.Op Fl bn
41.Op Fl M Ar core 41.Op Fl M Ar core
42.Op Fl N Ar system 42.Op Fl N Ar system
43.Op Fl t Ar turns 43.Op Fl t Ar turns
44.Op Fl w Ar wait 44.Op Fl w Ar wait
45.Op Ar display 45.Op Ar display
46.Op Ar refresh-interval 46.Op Ar refresh-interval
47.Sh DESCRIPTION 47.Sh DESCRIPTION
48.Nm 48.Nm
49displays various system statistics in a screen oriented fashion 49displays various system statistics in a screen oriented fashion
50using the curses screen display library, 50using the curses screen display library,
51.Xr curses 3 . 51.Xr curses 3 .
52.Pp 52.Pp
53While 53While
54.Nm 54.Nm
55is running the screen is usually divided into two windows (an exception 55is running the screen is usually divided into two windows (an exception
56is the vmstat display which uses the entire screen). 56is the vmstat display which uses the entire screen).
57The upper window depicts the current system load average. 57The upper window depicts the current system load average.
58The information displayed in the lower window may vary, depending on 58The information displayed in the lower window may vary, depending on
59user commands. 59user commands.
60The last line on the screen is reserved for user input and error messages. 60The last line on the screen is reserved for user input and error messages.
61.Pp 61.Pp
62By default 62By default
63.Nm 63.Nm
64displays the processes getting the largest percentage of the processor 64displays the processes getting the largest percentage of the processor
65in the lower window. 65in the lower window.
66Other displays show more detailed process information, 66Other displays show more detailed process information,
67swap space usage, 67swap space usage,
68disk usage statistics (a la 68disk usage statistics (a la
69.Xr df 1 ) , 69.Xr df 1 ) ,
70disk 70disk
71.Tn I/O 71.Tn I/O
72statistics (a la 72statistics (a la
73.Xr iostat 8 ) , 73.Xr iostat 8 ) ,
74virtual memory statistics (a la 74virtual memory statistics (a la
75.Xr vmstat 1 ) , 75.Xr vmstat 1 ) ,
76network ``mbuf'' utilization, network 'ifstat' traffic, and network connections (a la 76network ``mbuf'' utilization, network 'ifstat' traffic, and network connections (a la
77.Xr netstat 1 ) . 77.Xr netstat 1 ) .
78.Pp 78.Pp
79Input is interpreted at two different levels. 79Input is interpreted at two different levels.
80A ``global'' command interpreter processes all keyboard input. 80A ``global'' command interpreter processes all keyboard input.
81If this command interpreter fails to recognize a command, the 81If this command interpreter fails to recognize a command, the
82input line is passed to a per-display command interpreter. 82input line is passed to a per-display command interpreter.
83This allows each display to have certain display-specific commands. 83This allows each display to have certain display-specific commands.
84.Pp 84.Pp
85Command line options: 85Command line options:
86.Bl -tag -width "refresh_interval" 86.Bl -tag -width "refresh_interval"
87.It Fl M Ar core 87.It Fl M Ar core
88Extract values associated with the name list from 88Extract values associated with the name list from
89.Ar core 89.Ar core
90instead of the default 90instead of the default
91.Pa /dev/mem . 91.Pa /dev/mem .
92.It Fl N Ar system 92.It Fl N Ar system
93Extract the name list from 93Extract the name list from
94.Ar system 94.Ar system
95instead of the default 95instead of the default
96.Pa /netbsd . 96.Pa /netbsd .
97.It Fl b 97.It Fl b
98Show the chosen display once and exit. 98Show the chosen display once and exit.
99.It Fl n 99.It Fl n
100Do not resolve IP addresses into string hostnames 100Do not resolve IP addresses into string hostnames
101.Pq FQDNs 101.Pq FQDNs
102on 102on
103.Ic netstat . 103.Ic netstat .
104It has the same effect as 104It has the same effect as
105.Ic numbers 105.Ic numbers
106subcommand in 106subcommand in
107.Ic netstat . 107.Ic netstat .
108.It Fl w Ar wait 108.It Fl w Ar wait
109See 109See
110.Ar refresh-interval . 110.Ar refresh-interval .
111.It Fl t Ar turns 111.It Fl t Ar turns
112How many refreshes to show each screen in 'all' display mode. 112How many refreshes to show each screen in 'all' display mode.
113.It Ar display 113.It Ar display
114The 114The
115.Ar display 115.Ar display
116argument expects to be one of: 116argument expects to be one of:
117.Ic all , 117.Ic all ,
118.Ic bufcache , 118.Ic bufcache ,
119.Ic df , 119.Ic df ,
120.Ic ifstat , 120.Ic ifstat ,
121.Ic inet.icmp , 121.Ic inet.icmp ,
122.Ic inet.ip , 122.Ic inet.ip ,
123.Ic inet.tcp , 123.Ic inet.tcp ,
124.Ic inet.tcpsyn , 124.Ic inet.tcpsyn ,
125.Ic inet6.ip6 , 125.Ic inet6.ip6 ,
126.Ic iostat , 126.Ic iostat ,
127.Ic mbufs , 127.Ic mbufs ,
128.Ic netstat , 128.Ic netstat ,
129.Ic pigs , 129.Ic pigs ,
130.Ic ps , 130.Ic ps ,
131.Ic swap , 131.Ic swap ,
132.Ic syscall 132.Ic syscall
133or 133or
134.Ic vmstat . 134.Ic vmstat .
135These displays can also be requested interactively and are described in 135These displays can also be requested interactively and are described in
136full detail below. 136full detail below.
137.It Ar refresh-interval 137.It Ar refresh-interval
138The 138The
139.Ar refresh-interval 139.Ar refresh-interval
140specifies the screen refresh time interval in seconds. 140specifies the screen refresh time interval in seconds.
141This is provided for backwards compatibility, and overrides the 141This is provided for backwards compatibility, and overrides the
142.Ar refresh-interval 142.Ar refresh-interval
143specified with the 143specified with the
144.Fl w 144.Fl w
145flag. 145flag.
146.El 146.El
147.Pp 147.Pp
148Certain characters cause immediate action by 148Certain characters cause immediate action by
149.Nm . 149.Nm .
150These are 150These are
151.Bl -tag -width Fl 151.Bl -tag -width Fl
152.It Ic \&^L 152.It Ic \&^L
153Refresh the screen. 153Refresh the screen.
154.It Ic \&^G 154.It Ic \&^G
155Print the name of the current ``display'' being shown in 155Print the name of the current ``display'' being shown in
156the lower window and the refresh interval. 156the lower window and the refresh interval.
157.It Ic \&^Z 157.It Ic \&^Z
158Stop 158Stop
159.Nm . 159.Nm .
160.It Ic \&? , Ic h 160.It Ic \&? , Ic h
161Print the names of the available displays on the command line. 161Print the names of the available displays on the command line.
162.It Ic \&: 162.It Ic \&:
163Move the cursor to the command line and interpret the input 163Move the cursor to the command line and interpret the input
164line typed as a command. 164line typed as a command.
165While entering a command the current character erase, word erase, 165While entering a command the current character erase, word erase,
166and line kill characters may be used. 166and line kill characters may be used.
167.El 167.El
168.Pp 168.Pp
169The following commands are interpreted by the ``global'' 169The following commands are interpreted by the ``global''
170command interpreter. 170command interpreter.
171.Bl -tag -width Fl 171.Bl -tag -width Fl
172.It Ic help Ar key 172.It Ic help Ar key
173Print the names of the available displays on the command line. 173Print the names of the available displays on the command line.
174It will print long names as 174It will print long names as
175.Dq Ic inet.* . 175.Dq Ic inet.* .
176To print items under 176To print items under
177.Dq Ic inet , 177.Dq Ic inet ,
178give 178give
179.Ic inet 179.Ic inet
180as 180as
181.Ar key . 181.Ar key .
182.It Ic load 182.It Ic load
183Print the load average over the past 1, 5, and 15 minutes 183Print the load average over the past 1, 5, and 15 minutes
184on the command line. 184on the command line.
185.It Ic stop 185.It Ic stop
186Stop refreshing the screen. 186Stop refreshing the screen.
187.It Oo Ic start Oc Oo Ar number Oc 187.It Oo Ic start Oc Oo Ar number Oc
188Start (continue) refreshing the screen. 188Start (continue) refreshing the screen.
189If a second, numeric, argument is provided it is interpreted as a 189If a second, numeric, argument is provided it is interpreted as a
190refresh interval in seconds. 190refresh interval in seconds.
191Supplying only a number will set the refresh interval to this 191Supplying only a number will set the refresh interval to this
192value. 192value.
193.It Ic quit 193.It Ic quit
194Exit 194Exit
195.Nm . 195.Nm .
196(This may be abbreviated to 196(This may be abbreviated to
197.Ic q . ) 197.Ic q . )
198.El 198.El
199.Pp 199.Pp
200The available displays are: 200The available displays are:
201.Bl -tag -width Ic 201.Bl -tag -width Ic
202.It Ic all 202.It Ic all
203Cycle through all displays automatically. 203Cycle through all displays automatically.
204At each display, wait some 204At each display, wait some
205refresh-turns, then switch to the next display. 205refresh-turns, then switch to the next display.
206Duration of one refresh-turn is adjustable with the 206Duration of one refresh-turn is adjustable with the
207.Fl w 207.Fl w
208option, number of refresh-turns can be changed with the 208option, number of refresh-turns can be changed with the
209.Fl t 209.Fl t
210option. 210option.
211.It Ic bufcache 211.It Ic bufcache
212Display, in the lower window, statistics about the file system buffers. 212Display, in the lower window, statistics about the file system buffers.
213Statistics for each file system that has active buffers include the number 213Statistics for each file system that has active buffers include the number
214of buffers for that file system, the number of active kilobytes in those 214of buffers for that file system, the number of active kilobytes in those
215buffers and the total size of the buffers for that file system. 215buffers and the total size of the buffers for that file system.
216.It Ic df 216.It Ic df
217Lists disk usage statistics for all filesystems, 217Lists disk usage statistics for all filesystems,
218including the available free space as well as a bar 218including the available free space as well as a bar
219graph indicating the used capacity. 219graph indicating the used capacity.
220.Pp 220.Pp
221The following commands are specific to the 221The following commands are specific to the
222.Ic df 222.Ic df
223display: 223display:
224.Pp 224.Pp
225.Bl -tag -width Fl -compact 225.Bl -tag -width Fl -compact
226.It Cm all 226.It Cm all
227Displays information for all filesystems, including 227Displays information for all filesystems, including
228kernfs, procfs and null-mounts. 228kernfs, procfs and null-mounts.
229.It Cm some 229.It Cm some
230Suppress information about procfs, kernfs and null-mounts (default). 230Suppress information about procfs, kernfs and null-mounts (default).
231.El 231.El
232.It Ic ifstat 232.It Ic ifstat
233Display the network traffic going through active interfaces on the 233Display the network traffic going through active interfaces on the
234system. 234system.
235Idle interfaces will not be displayed until they receive some 235Idle interfaces will not be displayed until they receive some
236traffic. 236traffic.
237.Pp 237.Pp
238For each interface being displayed, the current, peak and total 238For each interface being displayed, the current, peak and total
239statistics are displayed for incoming and outgoing traffic. 239statistics are displayed for incoming and outgoing traffic.
240By default, 240By default,
241the 241the
242.Ic ifstat 242.Ic ifstat
243display will automatically scale the units being used so that they are 243display will automatically scale the units being used so that they are
244in a human-readable format. 244in a human-readable format.
245The scaling units used for the current and 245The scaling units used for the current and
246peak 246peak
247traffic columns can be altered by the 247traffic columns can be altered by the
248.Ic scale 248.Ic scale
249command. 249command.
250.Bl -tag -width ".Cm scale Op Ar units" 250.Bl -tag -width ".Cm scale Op Ar units"
251.It Cm scale Op Ar units 251.It Cm scale Op Ar units
252Modify the scale used to display the current and peak traffic over all 252Modify the scale used to display the current and peak traffic over all
253interfaces. 253interfaces.
254The following units are recognised: kbit, kbyte, mbit, 254The following units are recognised: kbit, kbyte, mbit,
255mbyte, gbit, gbyte and auto. 255mbyte, gbit, gbyte and auto.
256.It Cm pps 256.It Cm pps
257Show statistics in packets per second instead of bytes/bits per second. 257Show statistics in packets per second instead of bytes/bits per second.
258A subsequent call of 258A subsequent call of
259.Ic pps 259.Ic pps
260switches this mode off. 260switches this mode off.
261.It Cm match Op Ar patterns 261.It Cm match Op Ar patterns
262Display only interfaces that match pattern provided as an argument. 262Display only interfaces that match pattern provided as an argument.
263Patterns should be in shell syntax separated by whitespaces or commas. 263Patterns should be in shell syntax separated by whitespaces or commas.
264If this command is called without arguments then all interfaces are displayed. 264If this command is called without arguments then all interfaces are displayed.
265For example: 265For example:
266.Pp 266.Pp
267.Dl match re0, bge1 267.Dl match re0, bge1
268.Pp 268.Pp
269This will display re0 and bge1 interfaces. 269This will display re0 and bge1 interfaces.
270.Pp 270.Pp
271.Dl match re*, bge*, lo0 271.Dl match re*, bge*, lo0
272.Pp 272.Pp
273This will display all 273This will display all
274.Ic re 274.Ic re
275interfaces, all 275interfaces, all
276.Ic bge 276.Ic bge
277interfaces and the loopback interface. 277interfaces and the loopback interface.
278.El 278.El
279.Pp 279.Pp
280.It Ic inet.icmp 280.It Ic inet.icmp
281Display ICMP statistics. 281Display ICMP statistics.
282.It Ic inet.ip 282.It Ic inet.ip
283Display IPv4 and UDP statistics. 283Display IPv4 and UDP statistics.
284.It Ic inet.tcp 284.It Ic inet.tcp
285Display TCP statistics. 285Display TCP statistics.
286.It Ic inet.tcpsyn 286.It Ic inet.tcpsyn
287Display statistics about the 287Display statistics about the
288.Tn TCP 288.Tn TCP
289``syncache''. 289``syncache''.
290.It Ic inet6.ip6 290.It Ic inet6.ip6
291Display IPv6 statistics. 291Display IPv6 statistics.
292.It Ic iostat 292.It Ic iostat
293Display, in the lower window, statistics about processor use 293Display, in the lower window, statistics about processor use
294and disk throughput. 294and disk throughput.
295Statistics on processor use appear as bar graphs of the amount of 295Statistics on processor use appear as bar graphs of the amount of
296time executing in user mode (``user''), in user mode running low 296time executing in user mode (``user''), in user mode running low
297priority processes (``nice''), in system mode (``system''), and 297priority processes (``nice''), in system mode (``system''), and
298idle (``idle''). 298idle (``idle'').
299Statistics on disk throughput show, for each drive, kilobytes of 299Statistics on disk throughput show, for each drive, kilobytes of
300data transferred, number of disk transactions performed, and time 300data transferred, number of disk transactions performed, and time
301spent in disk accesses in milliseconds. 301spent in disk accesses in milliseconds.
302This information may be displayed as bar graphs or as rows of 302This information may be displayed as bar graphs or as rows of
303numbers which scroll downward. 303numbers which scroll downward.
304Bar graphs are shown by default; 304Bar graphs are shown by default;
305.Pp 305.Pp
306The following commands are specific to the 306The following commands are specific to the
307.Ic iostat 307.Ic iostat
308display; the minimum unambiguous prefix may be supplied. 308display; the minimum unambiguous prefix may be supplied.
309.Pp 309.Pp
310.Bl -tag -width Fl -compact 310.Bl -tag -width Fl -compact
311.It Cm numbers 311.It Cm numbers
312Show the disk 312Show the disk
313.Tn I/O 313.Tn I/O
314statistics in numeric form. 314statistics in numeric form.
315Values are 315Values are
316displayed in numeric columns which scroll downward. 316displayed in numeric columns which scroll downward.
317.It Cm bars 317.It Cm bars
318Show the disk 318Show the disk
319.Tn I/O 319.Tn I/O
320statistics in bar graph form (default). 320statistics in bar graph form (default).
321.It Cm secs 321.It Cm secs
322Toggle the display of time in disk activity (the default is to 322Toggle the display of time in disk activity (the default is to
323not display time). 323not display time).
324.It Cm all 324.It Cm all
325Show the read and write statistics combined (default). 325Show the read and write statistics combined (default).
326.It Cm rw 326.It Cm rw
327Show the read and write statistics separately. 327Show the read and write statistics separately.
328.El 328.El
329.It Ic mbufs 329.It Ic mbufs
330Display, in the lower window, the number of mbufs allocated 330Display, in the lower window, the number of mbufs allocated
331for particular uses, i.e. data, socket structures, etc. 331for particular uses, i.e. data, socket structures, etc.
332.It Ic netstat 332.It Ic netstat
333Display, in the lower window, network connections. 333Display, in the lower window, network connections.
334By default, network servers awaiting requests are not displayed. 334By default, network servers awaiting requests are not displayed.
335Each address is displayed in the format ``host.port'', with each 335Each address is displayed in the format ``host.port'', with each
336shown symbolically, when possible. 336shown symbolically, when possible.
337It is possible to have addresses displayed numerically, 337It is possible to have addresses displayed numerically,
338limit the display to a set of ports, hosts, and/or protocols 338limit the display to a set of ports, hosts, and/or protocols
339(the minimum unambiguous prefix may be supplied): 339(the minimum unambiguous prefix may be supplied):
340.Pp 340.Pp
341.Bl -tag -width Ar -compact 341.Bl -tag -width Ar -compact
342.It Cm all 342.It Cm all
343Toggle the displaying of server processes awaiting requests (this 343Toggle the displaying of server processes awaiting requests (this
344is the equivalent of the 344is the equivalent of the
345.Fl a 345.Fl a
346flag to 346flag to
347.Ar netstat 1 ) . 347.Ar netstat 1 ) .
348.It Cm numbers 348.It Cm numbers
349Display network addresses numerically. 349Display network addresses numerically.
350.It Cm names 350.It Cm names
351Display network addresses symbolically. 351Display network addresses symbolically.
352.It Ar protocol 352.It Ar protocol
353Display only network connections using the indicated protocol 353Display only network connections using the indicated protocol
354(currently either ``tcp'' or ``udp''). 354(currently either ``tcp'' or ``udp'').
355.It Cm ignore Op Ar items 355.It Cm ignore Op Ar items
356Do not display information about connections associated with 356Do not display information about connections associated with
357the specified hosts or ports. 357the specified hosts or ports.
358Hosts and ports may be specified by name (``vangogh'', ``ftp''), 358Hosts and ports may be specified by name (``vangogh'', ``ftp''),
359or numerically. 359or numerically.
360Host addresses use the Internet dot notation (``128.32.0.9''). 360Host addresses use the Internet dot notation (``128.32.0.9'').
361Multiple items may be specified with a single command by separating 361Multiple items may be specified with a single command by separating
362them with spaces. 362them with spaces.
363.It Cm display Op Ar items 363.It Cm display Op Ar items
364Display information about the connections associated with the 364Display information about the connections associated with the
365specified hosts or ports. 365specified hosts or ports.
366As for 366As for
367.Ar ignore , 367.Ar ignore ,
368.Op Ar items 368.Op Ar items
369may be names or numbers. 369may be names or numbers.
370.It Cm show Op Ar ports\&|hosts 370.It Cm show Op Ar ports\&|hosts
371Show, on the command line, the currently selected protocols, 371Show, on the command line, the currently selected protocols,
372hosts, and ports. 372hosts, and ports.
373Hosts and ports which are being ignored are prefixed with a `!'. 373Hosts and ports which are being ignored are prefixed with a `!'.
374If 374If
375.Ar ports 375.Ar ports
376or 376or
377.Ar hosts 377.Ar hosts
378is supplied as an argument to 378is supplied as an argument to
379.Cm show , 379.Cm show ,
380then only the requested information will be displayed. 380then only the requested information will be displayed.
381.It Cm reset 381.It Cm reset
382Reset the port, host, and protocol matching mechanisms to the default 382Reset the port, host, and protocol matching mechanisms to the default
383(any protocol, port, or host). 383(any protocol, port, or host).
384.El 384.El
385.It Ic pigs 385.It Ic pigs
386Display, in the lower window, those processes which are getting the 386Display, in the lower window, those processes which are getting the
387largest portion of the processor (the default display). 387largest portion of the processor (the default display).
388When less than 100% of the 388When less than 100% of the
389processor is scheduled to user processes, the remaining time 389processor is scheduled to user processes, the remaining time
390is accounted to the ``idle'' process. 390is accounted to the ``idle'' process.
391.It Ic ps 391.It Ic ps
392Display, in the lower window, the same information provided 392Display, in the lower window, the same information provided
393by the command 393by the command
394.Xr ps 1 394.Xr ps 1
395with the flags 395with the flags
396.Fl aux . 396.Fl aux .
397.Pp 397.Pp
398The following command is specific to the 398The following command is specific to the
399.Ic ps 399.Ic ps
400display; the minimum unambiguous prefix may be supplied. 400display; the minimum unambiguous prefix may be supplied.
401.Pp 401.Pp
402.Bl -tag -width Fl -compact 402.Bl -tag -width Fl -compact
403.It Cm user Ar name 403.It Cm user Ar name
404Limit the list of processes displayed to those owned by user 404Limit the list of processes displayed to those owned by user
405.Ar name . 405.Ar name .
406If 406If
407.Ar name 407.Ar name
408is specified as `+', processes owned by any user are displayed (default). 408is specified as `+', processes owned by any user are displayed (default).
409.El 409.El
410.It Ic swap 410.It Ic swap
411Show information about swap space usage on all the 411Show information about swap space usage on all the
412swap areas configured with 412swap areas configured with
413.Xr swapctl 8 . 413.Xr swapctl 8 .
414The first column is the device name of the partition. 414The first column is the device name of the partition.
415The next column is the total space available in the partition. 415The next column is the total space available in the partition.
416The 416The
417.Ar Used 417.Ar Used
418column indicates the total blocks used so far; 418column indicates the total blocks used so far;
419the graph shows the percentage of space in use on each partition. 419the graph shows the percentage of space in use on each partition.
420If there are more than one swap partition in use, 420If there are more than one swap partition in use,
421a total line is also shown. 421a total line is also shown.
422Areas known to the kernel, but not in use are shown as not available. 422Areas known to the kernel, but not in use are shown as not available.
423.It Ic syscall 423.It Ic syscall
424Show per system call statistics. 424Show per system call statistics.
425The display consists of several columns of system call name and counts. 425The display consists of several columns of system call name and counts.
426.Pp 426.Pp
427In order to stop entries moving around the screen too much, an infinite 427In order to stop entries moving around the screen too much, an infinite
428response filter is applied to the values before they are sorted. 428response filter is applied to the values before they are sorted.
429.Pp 429.Pp
430The following commands are specific to the 430The following commands are specific to the
431.Ic syscall 431.Ic syscall
432display: 432display:
433.Pp 433.Pp
434.Bl -tag -width Ar -compact 434.Bl -tag -width Ar -compact
435.It Ic sort Ic name 435.It Ic sort Ic name
436Sort display by the syscall name (default). 436Sort display by the syscall name (default).
437.It Ic sort Ic count 437.It Ic sort Ic count
438Sort display by the count of calls or time spent in the calls. 438Sort display by the count of calls or time spent in the calls.
439.It Ic sort Ic syscall 439.It Ic sort Ic syscall
440Sort display be syscall number. 440Sort display be syscall number.
441.It Ic show Ic count 441.It Ic show Ic count
442Show the number of times the system call has be called (default). 442Show the number of times the system call has be called (default).
443.It Ic show Ic time 443.It Ic show Ic time
444Show the average amount of time (in arbitrary units) spent in a call of 444Show the average amount of time (in arbitrary units) spent in a call of
445the syscall. 445the syscall.
446.El 446.El
447.It Ic vmstat 447.It Ic vmstat
448Take over the entire display and show a (rather crowded) compendium 448Take over the entire display and show a (rather crowded) compendium
449of statistics related to virtual memory usage, process scheduling, 449of statistics related to virtual memory usage, process scheduling,
450device interrupts, system name translation caching, disk 450device interrupts, system name translation caching, disk
451.Tn I/O 451.Tn I/O
452etc. 452etc.
453.Pp 453.Pp
454The upper left quadrant of the screen shows the number 454The upper left quadrant of the screen shows the number
455of users logged in and the load average over the last one, five, 455of users logged in and the load average over the last one, five,
456and fifteen minute intervals. 456and fifteen minute intervals.
457Below this is a list of the 457Below this are statistics on memory utilization.
 458The first row of the table reports memory usage only among
 459active processes, that is processes that have run in the previous
 460twenty seconds.
 461The second row reports on memory usage of all processes.
 462The first column reports on the number of physical pages
 463claimed by processes.
 464The second column reports the number of physical pages that
 465are devoted to read only text pages.
 466The third and fourth columns report the same two figures for
 467virtual pages, that is the number of pages that would be
 468needed if all processes had all of their pages.
 469Finally the last column shows the number of physical pages
 470on the free list.
 471.Pp
 472Below the memory display is a list of the
458average number of processes (over the last refresh interval) 473average number of processes (over the last refresh interval)
459that are runnable (`r'), in page wait (`p'), 474that are runnable (`r'), in page wait (`p'),
460in disk wait other than paging (`d'), sleeping (`s'). 475in disk wait other than paging (`d'), sleeping (`s').
461Below the queue length listing is a numerical listing and 476Below the queue length listing is a numerical listing and
462a bar graph showing the amount of 477a bar graph showing the amount of
463system (shown as `='), user (shown as `>'), 478system (shown as `='), user (shown as `>'),
464nice (shown as `-'), and idle time (shown as ` '). 479nice (shown as `-'), and idle time (shown as ` ').
465.Pp 480.Pp
466To the right of the process statistics is a column that 481To the right of the process statistics is a column that
467lists the average number of context switches (`Csw'), 482lists the average number of context switches (`Csw'),
468traps (`Trp'; includes page faults), system calls (`Sys'), interrupts (`Int'), 483traps (`Traps'; includes page faults), system calls (`SysCa'), interrupts (`Intr'),
469network software interrupts (`Sof'), 484network software interrupts (`Soft'),
470page faults (`Flt'). 485page faults (`Fault').
471.Pp 486.Pp
472Below this are statistics on memory utilization. 487Below this are statistics on memory utilization.
473The first row of the table reports memory usage only among 488The first row of the table reports memory usage only among
474active processes, that is processes that have run in the previous 489active processes, that is processes that have run in the previous
475twenty seconds. 490twenty seconds.
476The second row reports on memory usage of all processes. 491The second row reports on memory usage of all processes.
477The first column reports on the number of physical pages 492The first column reports on the number of physical pages
478claimed by processes. 493claimed by processes.
479The second column reports the number of pages of memory and swap. 494The second column reports the number of pages of memory and swap.
480The third column gives the number of pages of free memory and swap. 495The third column gives the number of pages of free memory and swap.
481.Pp 496.Pp
482Below the memory display are statistics on name translations. 497Below the memory display are statistics on name translations.
483It lists the number of names translated in the previous interval, 498It lists the number of names translated in the previous interval,
484the number and percentage of the translations that were 499the number and percentage of the translations that were
485handled by the system wide name translation cache, and 500handled by the system wide name translation cache, and
486the number and percentage of the translations that were 501the number and percentage of the translations that were
487handled by the per process name translation cache. 502handled by the per process name translation cache.
488.Pp 503.Pp
489At the bottom left is the disk usage display. 504At the bottom left is the disk usage display.
490It reports the number of seeks, transfers, number 505It reports the number of seeks, transfers, number
491of kilobyte blocks transferred per second averaged over the 506of kilobyte blocks transferred per second averaged over the
492refresh period of the display (by default, five seconds), and 507refresh period of the display (by default, five seconds), and
493the time spent in disk accesses. 508the time spent in disk accesses.
494If there are more than five disks, and the terminal window has more 509If there are more than five disks, and the terminal window has more
495than 24 lines, the disks display will be flipped so that more 510than 24 lines, the disks display will be flipped so that more
496of the disk statistics are visible. 511of the disk statistics are visible.
497.Pp 512.Pp
498Under the date in the upper right hand quadrant are statistics 513Under the date in the upper right hand quadrant are statistics
499on paging and swapping activity. 514on paging and swapping activity.
500The first two columns report the average number of pages 515The first two columns report the average number of pages
501brought in and out per second over the last refresh interval 516brought in and out per second over the last refresh interval
502due to page faults and the paging daemon. 517due to page faults and the paging daemon.
503The third and fourth columns report the average number of pages 518The third and fourth columns report the average number of pages
504brought in and out per second over the last refresh interval 519brought in and out per second over the last refresh interval
505due to swap requests initiated by the scheduler. 520due to swap requests initiated by the scheduler.
506The first row of the display shows the average 521The first row of the display shows the average
507number of disk transfers per second over the last refresh interval; 522number of disk transfers per second over the last refresh interval;
508the second row of the display shows the average 523the second row of the display shows the average
509number of pages transferred per second over the last refresh interval. 524number of pages transferred per second over the last refresh interval.
510.Pp 525.Pp
511Below the paging statistics is another columns of paging data. 526Below the paging statistics is another columns of paging data.
512From top to bottom, these represent average numbers of copy on write faults 527From top to bottom, these represent:
513(`cow'), object cache lookups (`objlk'), object cache hits (`objht'), 528.Pp
514pages zero filled on demand (`zfodw'), number zfod's created (`nzfod'), 529.Bl -tag -width Fl -compact
515percentage of zfod's used (`%zfod'), number of kernel pages (`kern'), 530.It Ic Sq forks
516number of wired pages (`wire'), number of active pages (`act'), number 531number of fork() calls
517of inactive pages (`inact'), number of free pages (`free'), pages freed 532.It Ic Sq fkppw
518by daemon (`daefr'), pages freed by exiting processes (`prcfr'), number 533number of fork() calls where parent waits
519of pages reactivated from freelist (`react'), scans in page out daemon 534.It Ic Sq fksvm
520(`scan'), revolutions of the hand (`hdrev'), and in-transit blocking page 535number of fork() calls where vmspace is shared
521faults (`intrn'), per second over the refresh period. 536.It Ic Sq pwait
 537number of times fault had to wait on a page
 538.It Ic Sq relck
 539number of times uvmfault_relock() is called
 540.It Ic Sq rlkok
 541number of times uvmfault_relock() is a success
 542.It Ic Sq noram
 543number of times fault was out of RAM
 544.It Ic Sq ndcpy
 545number of times fault clears ``needs copy''
 546.It Ic Sq fltcp
 547number of times fault promotes with copy (2b)
 548.It Ic Sq zfod
 549number of times fault promotes with zerofill (2b)
 550.It Ic Sq cow
 551number of times faulted for anonymous for Copy-On-Write (case 1b)
 552.It Ic Sq fmin
 553min number of free pages
 554.It Ic Sq ftarg
 555target number of free pages
 556.It Ic Sq itarg
 557target number of inactive pages
 558.\".It Ic Sq objlk
 559.\"object cache lookups
 560.\".It Ic Sq objht
 561.\"object cache hits
 562.\".It Ic Sq zfodw
 563.\"pages zero filled on demand
 564.\".It Ic Sq nzfod
 565.\"number of zfod's created
 566.\".It Ic Sq %zfod
 567.\"percentage of zfod's used
 568.\".It Ic Sq kern
 569.\"number of kernel pages
 570.It Ic Sq flnan
 571number of times fault was out of anonymous pages
 572.\".It Ic Sq act
 573.\"number of active pages
 574.\".It Ic Sq inact
 575.\"number of inactive pages
 576.\".It Ic Sq free
 577.\"number of free pages
 578.\".It Ic Sq daefr
 579.\"pages freed by daemon
 580.\".It Ic Sq prcfr
 581.\"pages freed by exiting processes
 582.\".It Ic Sq react
 583.\"number of pages reactivated from freelist
 584.\".It Ic Sq scan
 585.\"scans in page out daemon
 586.\".It Ic Sq hdrev
 587.\"revolutions of the hand
 588.\".It Ic Sq intrn
 589.\"in-transit blocking page faults per second over the refresh period.
 590.It Ic Sq pdfre
 591number of pages daemon freed since boot
 592.It Ic Sq pdscn
 593number of pages daemon scaned since boot
 594.El
 595.Pp
522Note that the `%zfod' percentage is usually less than 100%, 596Note that the `%zfod' percentage is usually less than 100%,
523however it may exceed 100% if a large number of requests 597however it may exceed 100% if a large number of requests
524are actually used long after they were set up during a 598are actually used long after they were set up during a
525period when no new pages are being set up. 599period when no new pages are being set up.
526Thus this figure is most interesting when observed over 600Thus this figure is most interesting when observed over
527a long time period, such as from boot time 601a long time period, such as from boot time
528(see below on getting such a display). 602(see below on getting such a display).
529.Pp 603.Pp
530To the left of the column of paging statistics is a breakdown 604To the left of the column of paging statistics is a breakdown
531of the interrupts being handled by the system. 605of the interrupts being handled by the system.
532At the top of the list is the total interrupts per second 606At the top of the list is the total interrupts per second
533over the time interval. 607over the time interval.
534The rest of the column breaks down the total on a device 608The rest of the column breaks down the total on a device
535by device basis. 609by device basis.
536Only devices that have interrupted at least once since boot time are shown. 610Only devices that have interrupted at least once since boot time are shown.
537.El 611.El
538.Pp 612.Pp
539Commands to switch between displays may be abbreviated to the 613Commands to switch between displays may be abbreviated to the
540minimum unambiguous prefix; for example, ``io'' for ``iostat''. 614minimum unambiguous prefix; for example, ``io'' for ``iostat''.
541Certain information may be discarded when the screen size is 615Certain information may be discarded when the screen size is
542insufficient for display. 616insufficient for display.
543For example, on a machine with 10 drives the 617For example, on a machine with 10 drives the
544.Ic iostat 618.Ic iostat
545bar graph displays only 3 drives on a 24 line terminal. 619bar graph displays only 3 drives on a 24 line terminal.
546When a bar graph would overflow the allotted screen space it is 620When a bar graph would overflow the allotted screen space it is
547truncated and the actual value is printed ``over top'' of the bar. 621truncated and the actual value is printed ``over top'' of the bar.
548.Pp 622.Pp
549The following commands are common to each display which shows 623The following commands are common to each display which shows
550information about disk drives. 624information about disk drives.
551These commands are used to select a set of drives to report on, 625These commands are used to select a set of drives to report on,
552should your system have more drives configured than can normally 626should your system have more drives configured than can normally
553be displayed on the screen. 627be displayed on the screen.
554Drives may be specified as drive names or as patterns specified in the 628Drives may be specified as drive names or as patterns specified in the
555notation described by 629notation described by
556.Xr fnmatch 3 . 630.Xr fnmatch 3 .
557.Pp 631.Pp
558.Bl -tag -width Ar -compact 632.Bl -tag -width Ar -compact
559.It Cm display Op Ar drives 633.It Cm display Op Ar drives
560Display information about the drives indicated. 634Display information about the drives indicated.
561Multiple drives may be specified, separated by spaces. 635Multiple drives may be specified, separated by spaces.
562.It Cm ignore Op Ar drives 636.It Cm ignore Op Ar drives
563Do not display information about the drives indicated. 637Do not display information about the drives indicated.
564Multiple drives may be specified, separated by spaces. 638Multiple drives may be specified, separated by spaces.
565.It Cm drives Op Ar drives 639.It Cm drives Op Ar drives
566With no arguments, display a list of available drives. 640With no arguments, display a list of available drives.
567With arguments, replace the list of currently displayed drives 641With arguments, replace the list of currently displayed drives
568with the ones specified. 642with the ones specified.
569.El 643.El
570.Pp 644.Pp
571The following commands are specific to the 645The following commands are specific to the
572.Ic inet.* , 646.Ic inet.* ,
573.Ic inet6.* , 647.Ic inet6.* ,
574.Ic syscall 648.Ic syscall
575and 649and
576.Ic vmstat 650.Ic vmstat
577displays; the minimum unambiguous prefix may be supplied. 651displays; the minimum unambiguous prefix may be supplied.
578.Pp 652.Pp
579.Bl -tag -width Ar -compact 653.Bl -tag -width Ar -compact
580.It Cm boot 654.It Cm boot
581Display cumulative statistics since the system was booted. 655Display cumulative statistics since the system was booted.
582.It Cm run 656.It Cm run
583Display statistics as a running total from the point this 657Display statistics as a running total from the point this
584command is given. 658command is given.
585.It Cm time 659.It Cm time
586Display statistics averaged over the refresh interval (the default). 660Display statistics averaged over the refresh interval (the default).
587.It Cm zero 661.It Cm zero
588Reset running statistics to zero. 662Reset running statistics to zero.
589.El 663.El
590.Sh FILES 664.Sh FILES
591.Bl -tag -width /etc/networks -compact 665.Bl -tag -width /etc/networks -compact
592.It Pa /netbsd 666.It Pa /netbsd
593For the namelist. 667For the namelist.
594.It Pa /dev/kmem 668.It Pa /dev/kmem
595For information in main memory. 669For information in main memory.
596.It Pa /etc/hosts 670.It Pa /etc/hosts
597For host names. 671For host names.
598.It Pa /etc/networks 672.It Pa /etc/networks
599For network names. 673For network names.
600.It Pa /etc/services 674.It Pa /etc/services
601For port names. 675For port names.
602.El 676.El
603.Sh NOTES 677.Sh NOTES
604Much of the information that 678Much of the information that
605.Nm 679.Nm
606.Ic vmstat 680.Ic vmstat
607uses is obtained from 681uses is obtained from
608.Cm struct vmmeter cnt . 682.Cm struct vmmeter cnt .
609.Sh SEE ALSO 683.Sh SEE ALSO
610.Xr df 1 , 684.Xr df 1 ,
611.Xr netstat 1 , 685.Xr netstat 1 ,
612.Xr ps 1 , 686.Xr ps 1 ,
613.Xr top 1 , 687.Xr top 1 ,
614.Xr vmstat 1 , 688.Xr vmstat 1 ,
615.Xr iostat 8 , 689.Xr iostat 8 ,
616.Xr pstat 8 690.Xr pstat 8
617.Sh HISTORY 691.Sh HISTORY
618The 692The
619.Nm 693.Nm
620program appeared in 694program appeared in
621.Bx 4.3 . 695.Bx 4.3 .
622.Sh BUGS 696.Sh BUGS
623Consumes CPU resources and thus may skew statistics. 697Consumes CPU resources and thus may skew statistics.
624.Pp 698.Pp
625Certain displays presume a minimum of 80 characters per line. 699Certain displays presume a minimum of 80 characters per line.
626.Pp 700.Pp
627The 701The
628.Ic vmstat 702.Ic vmstat
629display looks out of place because it is (it was added in as 703display looks out of place because it is (it was added in as
630a separate display from what used to be a different program). 704a separate display from what used to be a different program).
631.Pp 705.Pp
632The 706The
633.Fl b 707.Fl b
634option requires a real terminal and could be converted to 708option requires a real terminal and could be converted to
635simply output to standard output. 709simply output to standard output.

cvs diff -r1.11 -r1.12 src/usr.bin/systat/systat.h (switch to unified diff)

--- src/usr.bin/systat/systat.h 2005/02/26 22:12:34 1.11
+++ src/usr.bin/systat/systat.h 2018/12/26 01:47:37 1.12
@@ -1,64 +1,63 @@ @@ -1,64 +1,63 @@
1 1
2 2
3/*- 3/*-
4 * Copyright (c) 1980, 1989, 1992, 1993 4 * Copyright (c) 1980, 1989, 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 * 30 *
31 * @(#)systat.h 8.1 (Berkeley) 6/6/93 31 * @(#)systat.h 8.1 (Berkeley) 6/6/93
32 */ 32 */
33 33
34#include <curses.h> 34#include <curses.h>
35 35
36struct mode { 36struct mode {
37 const char *c_name; /* command name */ 37 const char *c_name; /* command name */
38 void (*c_refresh)(void); /* display refresh */ 38 void (*c_refresh)(void); /* display refresh */
39 void (*c_fetch)(void); /* sets up data structures */ 39 void (*c_fetch)(void); /* sets up data structures */
40 void (*c_label)(void); /* label display */ 40 void (*c_label)(void); /* label display */
41 int (*c_init)(void); /* initialize namelist, etc. */ 41 int (*c_init)(void); /* initialize namelist, etc. */
42 WINDOW *(*c_open)(void); /* open display */ 42 WINDOW *(*c_open)(void); /* open display */
43 void (*c_close)(WINDOW *); /* close display */ 43 void (*c_close)(WINDOW *); /* close display */
44 struct command *c_commands; /* commands for mode */ 44 struct command *c_commands; /* commands for mode */
45 char c_flags; /* see below */ 45 char c_flags; /* see below */
46}; 46};
47 47
48struct command { 48struct command {
49 const char *c_name; 49 const char *c_name;
50 void (*c_cmd)(char *args); 50 void (*c_cmd)(char *args);
51 const char *helptext; 51 const char *helptext;
52}; 52};
53 53
54#define CF_INIT 0x1 /* been initialized */ 54#define CF_INIT 0x1 /* been initialized */
55#define CF_LOADAV 0x2 /* display w/ load average */ 55#define CF_LOADAV 0x2 /* display w/ load average */
56 56
57#define TCP 0x1 57#define TCP 0x1
58#define UDP 0x2 58#define UDP 0x2
59 59
60#define KREAD(addr, buf, len) kvm_ckread((addr), (buf), (len), # addr) 60#define KREAD(addr, buf, len) kvm_ckread((addr), (buf), (len), # addr)
61#define NVAL(indx) namelist[(indx)].n_value 61#define NVAL(indx) namelist[(indx)].n_value
62#define NPTR(indx) (void *)NVAL((indx)) 62#define NPTR(indx) (void *)NVAL((indx))
63#define NREAD(indx, buf, len) kvm_ckread(NPTR((indx)), (buf), (len), # indx) 63#define NREAD(indx, buf, len) kvm_ckread(NPTR((indx)), (buf), (len), # indx)
64#define LONG (sizeof (long)) 

cvs diff -r1.82 -r1.83 src/usr.bin/systat/vmstat.c (switch to unified diff)

--- src/usr.bin/systat/vmstat.c 2017/07/15 08:22:23 1.82
+++ src/usr.bin/systat/vmstat.c 2018/12/26 01:47:37 1.83
@@ -1,859 +1,930 @@ @@ -1,859 +1,930 @@
1/* $NetBSD: vmstat.c,v 1.82 2017/07/15 08:22:23 mlelstv Exp $ */ 1/* $NetBSD: vmstat.c,v 1.83 2018/12/26 01:47:37 sevan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1983, 1989, 1992, 1993 4 * Copyright (c) 1983, 1989, 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94"; 35static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94";
36#endif 36#endif
37__RCSID("$NetBSD: vmstat.c,v 1.82 2017/07/15 08:22:23 mlelstv Exp $"); 37__RCSID("$NetBSD: vmstat.c,v 1.83 2018/12/26 01:47:37 sevan Exp $");
38#endif /* not lint */ 38#endif /* not lint */
39 39
40/* 40/*
41 * Cursed vmstat -- from Robert Elz. 41 * Cursed vmstat -- from Robert Elz.
42 */ 42 */
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/uio.h> 45#include <sys/uio.h>
46#include <sys/namei.h> 46#include <sys/namei.h>
47#include <sys/sysctl.h> 47#include <sys/sysctl.h>
48#include <sys/evcnt.h> 48#include <sys/evcnt.h>
49 49
50#include <uvm/uvm_extern.h> 50#include <uvm/uvm_extern.h>
51 51
52#include <errno.h> 52#include <errno.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <string.h> 54#include <string.h>
55#include <util.h> 55#include <util.h>
56 56
57#include "systat.h" 57#include "systat.h"
58#include "extern.h" 58#include "extern.h"
59#include "drvstats.h" 59#include "drvstats.h"
60#include "utmpentry.h" 60#include "utmpentry.h"
61#include "vmstat.h" 61#include "vmstat.h"
62 62
63static struct Info { 63static struct Info {
64 struct uvmexp_sysctl uvmexp; 64 struct uvmexp_sysctl uvmexp;
65 struct vmtotal Total; 65 struct vmtotal Total;
66 struct nchstats nchstats; 66 struct nchstats nchstats;
67 long nchcount; 67 long nchcount;
68 long *intrcnt; 68 long *intrcnt;
69 u_int64_t *evcnt; 69 u_int64_t *evcnt;
70} s, s1, s2, z; 70} s, s1, s2, z;
71 71
72enum display_mode display_mode = TIME; 72enum display_mode display_mode = TIME;
73 73
74static void allocinfo(struct Info *); 74static void allocinfo(struct Info *);
75static void copyinfo(struct Info *, struct Info *); 75static void copyinfo(struct Info *, struct Info *);
76static float cputime(int); 76static float cputime(int);
77static void dinfo(int, int, int); 77static void dinfo(int, int, int);
78static void getinfo(struct Info *); 78static void getinfo(struct Info *);
79static int ucount(void); 79static int ucount(void);
80 80
81static char buf[26]; 81static char buf[26];
82static u_int64_t temp; 82static u_int64_t temp;
83double etime; 83double etime;
84static float hertz; 84static float hertz;
85static int nintr; 85static int nintr;
86static long *intrloc; 86static long *intrloc;
87static char **intrname; 87static char **intrname;
88static int nextintsrow; 88static int nextintsrow;
89static int disk_horiz = 1; 89static int disk_horiz = 1;
 90static u_int nbuf;
90 91
91WINDOW * 92WINDOW *
92openvmstat(void) 93openvmstat(void)
93{ 94{
94 return (stdscr); 95 return (stdscr);
95} 96}
96 97
97void 98void
98closevmstat(WINDOW *w) 99closevmstat(WINDOW *w)
99{ 100{
100 101
101 if (w == NULL) 102 if (w == NULL)
102 return; 103 return;
103 wclear(w); 104 wclear(w);
104 wrefresh(w); 105 wrefresh(w);
105} 106}
106 107
107 108
108static struct nlist namelist[] = { 109static struct nlist namelist[] = {
109#define X_INTRNAMES 0 110#define X_INTRNAMES 0
110 { .n_name = "_intrnames" }, 111 { .n_name = "_intrnames" },
111#define X_EINTRNAMES 1 112#define X_EINTRNAMES 1
112 { .n_name = "_eintrnames" }, 113 { .n_name = "_eintrnames" },
113#define X_INTRCNT 2 114#define X_INTRCNT 2
114 { .n_name = "_intrcnt" }, 115 { .n_name = "_intrcnt" },
115#define X_EINTRCNT 3 116#define X_EINTRCNT 3
116 { .n_name = "_eintrcnt" }, 117 { .n_name = "_eintrcnt" },
117#define X_ALLEVENTS 4 118#define X_ALLEVENTS 4
118 { .n_name = "_allevents" }, 119 { .n_name = "_allevents" },
119 { .n_name = NULL } 120 { .n_name = NULL }
120}; 121};
121 122
122/* 123/*
123 * These constants define where the major pieces are laid out 124 * These constants define where the major pieces are laid out
124 */ 125 */
125#define STATROW 0 /* uses 1 row and 68 cols */ 126#define STATROW 0 /* uses 1 row and 68 cols */
126#define STATCOL 2 127#define STATCOL 2
127#define MEMROW 9 /* uses 4 rows and 31 cols */ 128#define MEMROW 9 /* uses 5 rows and 31 cols */
128#define MEMCOL 0 129#define MEMCOL 0
129#define PAGEROW 2 /* uses 4 rows and 26 cols */ 130#define PAGEROW 2 /* uses 4 rows and 26 cols */
130#define PAGECOL 54 131#define PAGECOL 54
131#define INTSROW 9 /* uses all rows to bottom and 17 cols */ 132#define INTSROW 9 /* uses all rows to bottom and 17 cols */
132#define INTSCOL 40 133#define INTSCOL 40
133#define INTSCOLEND (VMSTATCOL - 0) 134#define INTSCOLEND (VMSTATCOL - 0)
134#define PROCSROW 2 /* uses 2 rows and 20 cols */ 135#define PROCSROW 2 /* uses 2 rows and 20 cols */
135#define PROCSCOL 0 136#define PROCSCOL 0
136#define GENSTATROW 2 /* uses 2 rows and 30 cols */ 137#define GENSTATROW 2 /* uses 2 rows and 30 cols */
137#define GENSTATCOL 17 138#define GENSTATCOL 17
138#define VMSTATROW 7 /* uses 17 rows and 15 cols */ 139#define VMSTATROW 7 /* uses 17 rows and 15 cols */
139#define VMSTATCOL 64 140#define VMSTATCOL 64
140#define GRAPHROW 5 /* uses 3 rows and 51 cols */ 141#define GRAPHROW 5 /* uses 3 rows and 51 cols */
141#define GRAPHCOL 0 142#define GRAPHCOL 0
142#define NAMEIROW 14 /* uses 3 rows and 38 cols */ 143#define NAMEIROW 15 /* uses 3 rows and 38 cols (must be MEMROW + 5 + 1) */
143#define NAMEICOL 0 144#define NAMEICOL 0
144#define DISKROW 18 /* uses 5 rows and 50 cols (for 9 drives) */ 145#define DISKROW 19 /* uses 5 rows and 50 cols (for 9 drives) */
145#define DISKCOL 0 146#define DISKCOL 0
146#define DISKCOLWIDTH 6 147#define DISKCOLWIDTH 8
147#define DISKCOLEND INTSCOL 148#define DISKCOLEND INTSCOL
148 149
149typedef struct intr_evcnt intr_evcnt_t; 150typedef struct intr_evcnt intr_evcnt_t;
150struct intr_evcnt { 151struct intr_evcnt {
151 char *ie_group; 152 char *ie_group;
152 char *ie_name; 153 char *ie_name;
153 u_int64_t *ie_count; /* kernel address... */ 154 u_int64_t *ie_count; /* kernel address... */
154 int ie_loc; /* screen row */ 155 int ie_loc; /* screen row */
155} *ie_head; 156} *ie_head;
156int nevcnt; 157int nevcnt;
157 158
158static void 159static void
159get_interrupt_events(void) 160get_interrupt_events(void)
160{ 161{
161 struct evcntlist allevents; 162 struct evcntlist allevents;
162 struct evcnt evcnt, *evptr; 163 struct evcnt evcnt, *evptr;
163 intr_evcnt_t *ie; 164 intr_evcnt_t *ie;
164 intr_evcnt_t *n; 165 intr_evcnt_t *n;
165 166
166 if (!NREAD(X_ALLEVENTS, &allevents, sizeof allevents)) 167 if (!NREAD(X_ALLEVENTS, &allevents, sizeof allevents))
167 return; 168 return;
168 evptr = TAILQ_FIRST(&allevents); 169 evptr = TAILQ_FIRST(&allevents);
169 for (; evptr != NULL; evptr = TAILQ_NEXT(&evcnt, ev_list)) { 170 for (; evptr != NULL; evptr = TAILQ_NEXT(&evcnt, ev_list)) {
170 if (!KREAD(evptr, &evcnt, sizeof evcnt)) 171 if (!KREAD(evptr, &evcnt, sizeof evcnt))
171 return; 172 return;
172 if (evcnt.ev_type != EVCNT_TYPE_INTR) 173 if (evcnt.ev_type != EVCNT_TYPE_INTR)
173 continue; 174 continue;
174 n = realloc(ie_head, sizeof *ie * (nevcnt + 1)); 175 n = realloc(ie_head, sizeof *ie * (nevcnt + 1));
175 if (n == NULL) { 176 if (n == NULL) {
176 error("realloc failed"); 177 error("realloc failed");
177 die(0); 178 die(0);
178 } 179 }
179 ie_head = n; 180 ie_head = n;
180 ie = ie_head + nevcnt; 181 ie = ie_head + nevcnt;
181 ie->ie_group = malloc(evcnt.ev_grouplen + 1); 182 ie->ie_group = malloc(evcnt.ev_grouplen + 1);
182 ie->ie_name = malloc(evcnt.ev_namelen + 1); 183 ie->ie_name = malloc(evcnt.ev_namelen + 1);
183 if (ie->ie_group == NULL || ie->ie_name == NULL) 184 if (ie->ie_group == NULL || ie->ie_name == NULL)
184 return; 185 return;
185 if (!KREAD(evcnt.ev_group, ie->ie_group, evcnt.ev_grouplen + 1)) 186 if (!KREAD(evcnt.ev_group, ie->ie_group, evcnt.ev_grouplen + 1))
186 return; 187 return;
187 if (!KREAD(evcnt.ev_name, ie->ie_name, evcnt.ev_namelen + 1)) 188 if (!KREAD(evcnt.ev_name, ie->ie_name, evcnt.ev_namelen + 1))
188 return; 189 return;
189 ie->ie_count = &evptr->ev_count; 190 ie->ie_count = &evptr->ev_count;
190 ie->ie_loc = 0; 191 ie->ie_loc = 0;
191 nevcnt++; 192 nevcnt++;
192 } 193 }
193} 194}
194 195
195int 196int
196initvmstat(void) 197initvmstat(void)
197{ 198{
198 static char *intrnamebuf; 199 static char *intrnamebuf;
199 char *cp; 200 char *cp;
200 int i; 201 int i;
201 202
202 if (intrnamebuf) 203 if (intrnamebuf)
203 free(intrnamebuf); 204 free(intrnamebuf);
204 if (intrname) 205 if (intrname)
205 free(intrname); 206 free(intrname);
206 if (intrloc) 207 if (intrloc)
207 free(intrloc); 208 free(intrloc);
208 209
209 if (namelist[0].n_type == 0) { 210 if (namelist[0].n_type == 0) {
210 if (kvm_nlist(kd, namelist) && 211 if (kvm_nlist(kd, namelist) &&
211 namelist[X_ALLEVENTS].n_type == 0) { 212 namelist[X_ALLEVENTS].n_type == 0) {
212 nlisterr(namelist); 213 nlisterr(namelist);
213 return(0); 214 return(0);
214 } 215 }
215 } 216 }
216 hertz = stathz ? stathz : hz; 217 hertz = stathz ? stathz : hz;
217 if (!drvinit(1)) 218 if (!drvinit(1))
218 return(0); 219 return(0);
219 220
220 /* Old style interrupt counts - deprecated */ 221 /* Old style interrupt counts - deprecated */
221 nintr = (namelist[X_EINTRCNT].n_value - 222 nintr = (namelist[X_EINTRCNT].n_value -
222 namelist[X_INTRCNT].n_value) / sizeof (long); 223 namelist[X_INTRCNT].n_value) / sizeof (long);
223 if (nintr) { 224 if (nintr) {
224 intrloc = calloc(nintr, sizeof (long)); 225 intrloc = calloc(nintr, sizeof (long));
225 intrname = calloc(nintr, sizeof (long)); 226 intrname = calloc(nintr, sizeof (long));
226 intrnamebuf = malloc(namelist[X_EINTRNAMES].n_value - 227 intrnamebuf = malloc(namelist[X_EINTRNAMES].n_value -
227 namelist[X_INTRNAMES].n_value); 228 namelist[X_INTRNAMES].n_value);
228 if (intrnamebuf == NULL || intrname == 0 || intrloc == 0) { 229 if (intrnamebuf == NULL || intrname == 0 || intrloc == 0) {
229 error("Out of memory\n"); 230 error("Out of memory\n");
230 nintr = 0; 231 nintr = 0;
231 return(0); 232 return(0);
232 } 233 }
233 NREAD(X_INTRNAMES, intrnamebuf, NVAL(X_EINTRNAMES) - 234 NREAD(X_INTRNAMES, intrnamebuf, NVAL(X_EINTRNAMES) -
234 NVAL(X_INTRNAMES)); 235 NVAL(X_INTRNAMES));
235 for (cp = intrnamebuf, i = 0; i < nintr; i++) { 236 for (cp = intrnamebuf, i = 0; i < nintr; i++) {
236 intrname[i] = cp; 237 intrname[i] = cp;
237 cp += strlen(cp) + 1; 238 cp += strlen(cp) + 1;
238 } 239 }
239 } 240 }
240 241
241 /* event counter interrupt counts */ 242 /* event counter interrupt counts */
242 get_interrupt_events(); 243 get_interrupt_events();
243 244
244 nextintsrow = INTSROW + 1; 245 nextintsrow = INTSROW + 1;
245 allocinfo(&s); 246 allocinfo(&s);
246 allocinfo(&s1); 247 allocinfo(&s1);
247 allocinfo(&s2); 248 allocinfo(&s2);
248 allocinfo(&z); 249 allocinfo(&z);
249 250
250 getinfo(&s2); 251 getinfo(&s2);
251 copyinfo(&s2, &s1); 252 copyinfo(&s2, &s1);
252 return(1); 253 return(1);
253} 254}
254 255
255void 256void
256fetchvmstat(void) 257fetchvmstat(void)
257{ 258{
258 time_t now; 259 time_t now;
259 260
260 time(&now); 261 time(&now);
261 strlcpy(buf, ctime(&now), sizeof(buf)); 262 strlcpy(buf, ctime(&now), sizeof(buf));
262 buf[19] = '\0'; 263 buf[19] = '\0';
263 getinfo(&s); 264 getinfo(&s);
264} 265}
265 266
266static void 267static void
267print_ie_title(int i) 268print_ie_title(int i)
268{ 269{
269 int width, name_width, group_width; 270 int width, name_width, group_width;
270 271
271 width = INTSCOLEND - (INTSCOL + 9); 272 width = INTSCOLEND - (INTSCOL + 9);
272 if (width <= 0) 273 if (width <= 0)
273 return; 274 return;
274 275
275 move(ie_head[i].ie_loc, INTSCOL + 9); 276 move(ie_head[i].ie_loc, INTSCOL + 9);
276 group_width = strlen(ie_head[i].ie_group); 277 group_width = strlen(ie_head[i].ie_group);
277 name_width = strlen(ie_head[i].ie_name); 278 name_width = strlen(ie_head[i].ie_name);
278 width -= group_width + 1 + name_width; 279 width -= group_width + 1 + name_width;
279 if (width < 0) { 280 if (width < 0) {
280 /* 281 /*
281 * Screen to narrow for full strings 282 * Screen to narrow for full strings
282 * This is all rather horrid, in some cases there are a lot 283 * This is all rather horrid, in some cases there are a lot
283 * of events in the same group, and in others the event 284 * of events in the same group, and in others the event
284 * name is "intr". There are also names which need 7 or 8 285 * name is "intr". There are also names which need 7 or 8
285 * columns before they become meaningful. 286 * columns before they become meaningful.
286 * This is a bad compromise. 287 * This is a bad compromise.
287 */ 288 */
288 width = -width; 289 width = -width;
289 group_width -= (width + 1) / 2; 290 group_width -= (width + 1) / 2;
290 name_width -= width / 2; 291 name_width -= width / 2;
291 /* some have the 'useful' name "intr", display their group */ 292 /* some have the 'useful' name "intr", display their group */
292 if (strcasecmp(ie_head[i].ie_name, "intr") == 0) { 293 if (strcasecmp(ie_head[i].ie_name, "intr") == 0) {
293 group_width += name_width + 1; 294 group_width += name_width + 1;
294 name_width = 0; 295 name_width = 0;
295 } else { 296 } else {
296 if (group_width <= 3 || name_width < 0) { 297 if (group_width <= 3 || name_width < 0) {
297 /* don't display group */ 298 /* don't display group */
298 name_width += group_width + 1; 299 name_width += group_width + 1;
299 group_width = 0; 300 group_width = 0;
300 } 301 }
301 } 302 }
302 } 303 }
303 304
304 if (group_width != 0) { 305 if (group_width != 0) {
305 printw("%-.*s", group_width, ie_head[i].ie_group); 306 printw("%-.*s", group_width, ie_head[i].ie_group);
306 if (name_width != 0) 307 if (name_width != 0)
307 printw(" "); 308 printw(" ");
308 } 309 }
309 if (name_width != 0) 310 if (name_width != 0)
310 printw("%-.*s", name_width, ie_head[i].ie_name); 311 printw("%-.*s", name_width, ie_head[i].ie_name);
311} 312}
312 313
313void 314void
314labelvmstat_top(void) 315labelvmstat_top(void)
315{ 316{
316 317
317 clear(); 318 clear();
318 319
319 mvprintw(STATROW, STATCOL + 4, "users Load"); 320 mvprintw(STATROW, STATCOL + 4, "users Load");
320 321
321 mvprintw(GENSTATROW, GENSTATCOL, " Csw Trp Sys Int Sof Flt"); 322 mvprintw(GENSTATROW, GENSTATCOL, " Csw Traps SysCal Intr Soft Fault");
322 323
323 mvprintw(GRAPHROW, GRAPHCOL, 324 mvprintw(GRAPHROW, GRAPHCOL,
324 " . %% Sy . %% Us . %% Ni . %% In . %% Id"); 325 " . %% Sy . %% Us . %% Ni . %% In . %% Id");
325 mvprintw(PROCSROW, PROCSCOL, "Proc:r d s"); 326 mvprintw(PROCSROW, PROCSCOL, "Proc:r d s");
326 mvprintw(GRAPHROW + 1, GRAPHCOL, 327 mvprintw(GRAPHROW + 1, GRAPHCOL,
327 "| | | | | | | | | | |"); 328 "| | | | | | | | | | |");
328 329
329 mvprintw(PAGEROW, PAGECOL + 8, "PAGING SWAPPING "); 330 mvprintw(PAGEROW, PAGECOL + 8, "PAGING SWAPPING ");
330 mvprintw(PAGEROW + 1, PAGECOL, " in out in out "); 331 mvprintw(PAGEROW + 1, PAGECOL, " in out in out ");
331 mvprintw(PAGEROW + 2, PAGECOL + 2, "ops"); 332 mvprintw(PAGEROW + 2, PAGECOL, " ops ");
332 mvprintw(PAGEROW + 3, PAGECOL, "pages"); 333 mvprintw(PAGEROW + 3, PAGECOL, "pages ");
333} 334}
334 335
335void 336void
336labelvmstat(void) 337labelvmstat(void)
337{ 338{
338 int i; 339 int i;
339 340
340 /* Top few lines first */ 341 /* Top few lines first */
341 342
342 labelvmstat_top(); 343 labelvmstat_top();
343 344
344 /* Left hand column */ 345 /* Left hand column */
345 346
346 mvprintw(MEMROW, MEMCOL, " memory totals (in kB)"); 347 mvprintw(MEMROW + 0, MEMCOL, "Anon %% zero ");
347 mvprintw(MEMROW + 1, MEMCOL, " real virtual free"); 348 mvprintw(MEMROW + 1, MEMCOL, "Exec %% wired ");
348 mvprintw(MEMROW + 2, MEMCOL, "Active"); 349 mvprintw(MEMROW + 2, MEMCOL, "File %% inact ");
349 mvprintw(MEMROW + 3, MEMCOL, "All"); 350 mvprintw(MEMROW + 3, MEMCOL, "Meta %% bufs ");
 351 mvprintw(MEMROW + 4, MEMCOL, " (kB) real swaponly free");
 352 mvprintw(MEMROW + 5, MEMCOL, "Active ");
350 353
351 mvprintw(NAMEIROW, NAMEICOL, "Namei Sys-cache Proc-cache"); 354 mvprintw(NAMEIROW, NAMEICOL, "Namei Sys-cache Proc-cache");
352 mvprintw(NAMEIROW + 1, NAMEICOL, 355 mvprintw(NAMEIROW + 1, NAMEICOL,
353 " Calls hits %% hits %%"); 356 " Calls hits %% hits %%");
354 357
355 mvprintw(DISKROW, DISKCOL, "Disks:"); 358 mvprintw(DISKROW, DISKCOL, "%*s", DISKCOLWIDTH, "Disks:");
356 if (disk_horiz) { 359 if (disk_horiz) {
357 mvprintw(DISKROW + 1, DISKCOL + 1, "seeks"); 360 mvprintw(DISKROW + 1, DISKCOL + 1, "seeks");
358 mvprintw(DISKROW + 2, DISKCOL + 1, "xfers"); 361 mvprintw(DISKROW + 2, DISKCOL + 1, "xfers");
359 mvprintw(DISKROW + 3, DISKCOL + 1, "bytes"); 362 mvprintw(DISKROW + 3, DISKCOL + 1, "bytes");
360 mvprintw(DISKROW + 4, DISKCOL + 1, "%%busy"); 363 mvprintw(DISKROW + 4, DISKCOL + 1, "%%busy");
361 } else { 364 } else {
362 mvprintw(DISKROW, DISKCOL + 1 + 1 * DISKCOLWIDTH, "seeks"); 365 mvprintw(DISKROW, DISKCOL + 1 * DISKCOLWIDTH, "%*s", DISKCOLWIDTH, "seeks");
363 mvprintw(DISKROW, DISKCOL + 1 + 2 * DISKCOLWIDTH, "xfers"); 366 mvprintw(DISKROW, DISKCOL + 2 * DISKCOLWIDTH, "%*s", DISKCOLWIDTH, "xfers");
364 mvprintw(DISKROW, DISKCOL + 1 + 3 * DISKCOLWIDTH, "bytes"); 367 mvprintw(DISKROW, DISKCOL + 3 * DISKCOLWIDTH, "%*s", DISKCOLWIDTH, "bytes");
365 mvprintw(DISKROW, DISKCOL + 1 + 4 * DISKCOLWIDTH, "%%busy"); 368 mvprintw(DISKROW, DISKCOL + 4 * DISKCOLWIDTH, "%*s", DISKCOLWIDTH, "%%busy");
366 } 369 }
367 370
368 /* Middle column */ 371 /* Middle column */
369 372
370 mvprintw(INTSROW, INTSCOL + 9, "Interrupts"); 373 mvprintw(INTSROW, INTSCOL + 9, "Interrupts");
371 for (i = 0; i < nintr; i++) { 374 for (i = 0; i < nintr; i++) {
372 if (intrloc[i] == 0) 375 if (intrloc[i] == 0)
373 continue; 376 continue;
374 mvprintw(intrloc[i], INTSCOL + 9, "%-.*s", 377 mvprintw(intrloc[i], INTSCOL + 9, "%-.*s",
375 INTSCOLEND - (INTSCOL + 9), intrname[i]); 378 INTSCOLEND - (INTSCOL + 9), intrname[i]);
376 } 379 }
377 for (i = 0; i < nevcnt; i++) { 380 for (i = 0; i < nevcnt; i++) {
378 if (ie_head[i].ie_loc == 0) 381 if (ie_head[i].ie_loc == 0)
379 continue; 382 continue;
380 print_ie_title(i); 383 print_ie_title(i);
381 } 384 }
382 385
383 /* Right hand column */ 386 /* Right hand column */
384 387
385 mvprintw(VMSTATROW + 0, VMSTATCOL + 10, "forks"); 388 mvprintw(VMSTATROW + 0, VMSTATCOL + 10, "forks");
386 mvprintw(VMSTATROW + 1, VMSTATCOL + 10, "fkppw"); 389 mvprintw(VMSTATROW + 1, VMSTATCOL + 10, "fkppw");
387 mvprintw(VMSTATROW + 2, VMSTATCOL + 10, "fksvm"); 390 mvprintw(VMSTATROW + 2, VMSTATCOL + 10, "fksvm");
388 mvprintw(VMSTATROW + 3, VMSTATCOL + 10, "pwait"); 391 mvprintw(VMSTATROW + 3, VMSTATCOL + 10, "pwait");
389 mvprintw(VMSTATROW + 4, VMSTATCOL + 10, "relck"); 392 mvprintw(VMSTATROW + 4, VMSTATCOL + 10, "relck");
390 mvprintw(VMSTATROW + 5, VMSTATCOL + 10, "rlkok"); 393 mvprintw(VMSTATROW + 5, VMSTATCOL + 10, "rlkok");
391 mvprintw(VMSTATROW + 6, VMSTATCOL + 10, "noram"); 394 mvprintw(VMSTATROW + 6, VMSTATCOL + 10, "noram");
392 mvprintw(VMSTATROW + 7, VMSTATCOL + 10, "ndcpy"); 395 mvprintw(VMSTATROW + 7, VMSTATCOL + 10, "ndcpy");
393 mvprintw(VMSTATROW + 8, VMSTATCOL + 10, "fltcp"); 396 mvprintw(VMSTATROW + 8, VMSTATCOL + 10, "fltcp");
394 mvprintw(VMSTATROW + 9, VMSTATCOL + 10, "zfod"); 397 mvprintw(VMSTATROW + 9, VMSTATCOL + 10, "zfod");
395 mvprintw(VMSTATROW + 10, VMSTATCOL + 10, "cow"); 398 mvprintw(VMSTATROW + 10, VMSTATCOL + 10, "cow");
396 mvprintw(VMSTATROW + 11, VMSTATCOL + 10, "fmin"); 399 mvprintw(VMSTATROW + 11, VMSTATCOL + 10, "fmin");
397 mvprintw(VMSTATROW + 12, VMSTATCOL + 10, "ftarg"); 400 mvprintw(VMSTATROW + 12, VMSTATCOL + 10, "ftarg");
398 mvprintw(VMSTATROW + 13, VMSTATCOL + 10, "itarg"); 401 mvprintw(VMSTATROW + 13, VMSTATCOL + 10, "itarg");
399 mvprintw(VMSTATROW + 14, VMSTATCOL + 10, "wired"); 402 mvprintw(VMSTATROW + 14, VMSTATCOL + 10, "flnan");
400 mvprintw(VMSTATROW + 15, VMSTATCOL + 10, "pdfre"); 403 mvprintw(VMSTATROW + 15, VMSTATCOL + 10, "pdfre");
401 404
402 if (LINES - 1 > VMSTATROW + 16) 405 if (LINES - 1 > VMSTATROW + 16)
403 mvprintw(VMSTATROW + 16, VMSTATCOL + 10, "pdscn"); 406 mvprintw(VMSTATROW + 16, VMSTATCOL + 10, "pdscn");
404} 407}
405 408
406#define X(s, s1, fld) {temp = (s).fld[i]; (s).fld[i] -= (s1).fld[i]; \ 409#define X(s, s1, fld) {temp = (s).fld[i]; (s).fld[i] -= (s1).fld[i]; \
407 if (display_mode == TIME) (s1).fld[i] = temp;} 410 if (display_mode == TIME) (s1).fld[i] = temp;}
408#define Z(s, s1, fld) {temp = (s).nchstats.fld; \ 411#define Z(s, s1, fld) {temp = (s).nchstats.fld; \
409 (s).nchstats.fld -= (s1).nchstats.fld; \ 412 (s).nchstats.fld -= (s1).nchstats.fld; \
410 if (display_mode == TIME) (s1).nchstats.fld = temp;} 413 if (display_mode == TIME) (s1).nchstats.fld = temp;}
411#define PUTRATE(s, s1, fld, l, c, w) \ 414#define PUTRATE(s, s1, fld, l, c, w) \
412 {temp = (s).fld; (s).fld -= (s1).fld; \ 415 {temp = (s).fld; (s).fld -= (s1).fld; \
413 if (display_mode == TIME) (s1).fld = temp; \ 416 if (display_mode == TIME) (s1).fld = temp; \
414 putint((int)((float)(s).fld/etime + 0.5), l, c, w);} 417 putint((int)((float)(s).fld/etime + 0.5), l, c, w);}
415#define MAXFAIL 5 418#define MAXFAIL 5
416 419
417static char cpuchar[CPUSTATES] = { '=' , '>', '-', '%', ' ' }; 420static char cpuchar[CPUSTATES] = { '=' , '>', '-', '%', ' ' };
418static char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_INTR, CP_IDLE }; 421static char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_INTR, CP_IDLE };
419 422
420void 423void
421show_vmstat_top(vmtotal_t *Total, uvmexp_sysctl_t *uvm, uvmexp_sysctl_t *uvm1) 424show_vmstat_top(vmtotal_t *Total, uvmexp_sysctl_t *uvm, uvmexp_sysctl_t *uvm1)
422{ 425{
423 float f1, f2; 426 float f1, f2;
424 int psiz; 427 int psiz;
425 int i, l, c; 428 int i, l, c;
426 struct { 429 struct {
427 struct uvmexp_sysctl *uvmexp; 430 struct uvmexp_sysctl *uvmexp;
428 } us, us1; 431 } us, us1;
429 432
430 us.uvmexp = uvm; 433 us.uvmexp = uvm;
431 us1.uvmexp = uvm1; 434 us1.uvmexp = uvm1;
432 435
433 putint(ucount(), STATROW, STATCOL, 3); 436 putint(ucount(), STATROW, STATCOL, 3);
434 putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0); 437 putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0);
435 putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0); 438 putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0);
436 putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0); 439 putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0);
437 mvaddstr(STATROW, STATCOL + 53, buf); 440 mvaddstr(STATROW, STATCOL + 53, buf);
438 441
439 putint(Total->t_rq - 1, PROCSROW + 1, PROCSCOL + 3, 3); 442 putint(Total->t_rq - 1, PROCSROW + 1, PROCSCOL + 3, 3);
440 putint(Total->t_dw, PROCSROW + 1, PROCSCOL + 6, 3); 443 putint(Total->t_dw, PROCSROW + 1, PROCSCOL + 6, 3);
441 putint(Total->t_sl, PROCSROW + 1, PROCSCOL + 9, 3); 444 putint(Total->t_sl, PROCSROW + 1, PROCSCOL + 9, 3);
442 445
443 PUTRATE(us, us1, uvmexp->swtch, GENSTATROW + 1, GENSTATCOL - 1, 7); 446 PUTRATE(us, us1, uvmexp->swtch, GENSTATROW + 1, GENSTATCOL - 1, 7);
444 PUTRATE(us, us1, uvmexp->traps, GENSTATROW + 1, GENSTATCOL + 7, 6); 447 PUTRATE(us, us1, uvmexp->traps, GENSTATROW + 1, GENSTATCOL + 7, 6);
445 PUTRATE(us, us1, uvmexp->syscalls, GENSTATROW + 1, GENSTATCOL + 14, 6); 448 PUTRATE(us, us1, uvmexp->syscalls, GENSTATROW + 1, GENSTATCOL + 14, 6);
446 PUTRATE(us, us1, uvmexp->intrs, GENSTATROW + 1, GENSTATCOL + 21, 5); 449 PUTRATE(us, us1, uvmexp->intrs, GENSTATROW + 1, GENSTATCOL + 21, 5);
447 PUTRATE(us, us1, uvmexp->softs, GENSTATROW + 1, GENSTATCOL + 27, 6); 450 PUTRATE(us, us1, uvmexp->softs, GENSTATROW + 1, GENSTATCOL + 27, 6);
448 PUTRATE(us, us1, uvmexp->faults, GENSTATROW + 1, GENSTATCOL + 34, 6); 451 PUTRATE(us, us1, uvmexp->faults, GENSTATROW + 1, GENSTATCOL + 34, 6);
449 452
 453 /*
 454 * XXX it sure would be nice if this did what top(1) does and showed
 455 * the utilization of each CPU on a separate line, though perhaps IFF
 456 * the screen is tall enough
 457 */
450 /* Last CPU state not calculated yet. */ 458 /* Last CPU state not calculated yet. */
451 for (f2 = 0.0, psiz = 0, c = 0; c < CPUSTATES; c++) { 459 for (f2 = 0.0, psiz = 0, c = 0; c < CPUSTATES; c++) {
452 i = cpuorder[c]; 460 i = cpuorder[c];
453 f1 = cputime(i); 461 f1 = cputime(i);
454 f2 += f1; 462 f2 += f1;
455 l = (int) ((f2 + 1.0) / 2.0) - psiz; 463 l = (int) ((f2 + 1.0) / 2.0) - psiz;
456 if (c == 0) 464 if (c == 0)
457 putfloat(f1, GRAPHROW, GRAPHCOL + 1, 5, 1, 0); 465 putfloat(f1, GRAPHROW, GRAPHCOL + 1, 5, 1, 0);
458 else 466 else
459 putfloat(f1, GRAPHROW, GRAPHCOL + 10 * c + 1, 5, 1, 0); 467 putfloat(f1, GRAPHROW, GRAPHCOL + 10 * c + 1, 5, 1, 0);
460 mvhline(GRAPHROW + 2, psiz, cpuchar[c], l); 468 mvhline(GRAPHROW + 2, psiz, cpuchar[c], l);
461 psiz += l; 469 psiz += l;
462 } 470 }
463 471
464 PUTRATE(us, us1, uvmexp->pageins, PAGEROW + 2, PAGECOL + 5, 5); 472 PUTRATE(us, us1, uvmexp->pageins, PAGEROW + 2, PAGECOL + 5, 5);
465 PUTRATE(us, us1, uvmexp->pdpageouts, PAGEROW + 2, PAGECOL + 10, 5); 473 PUTRATE(us, us1, uvmexp->pdpageouts, PAGEROW + 2, PAGECOL + 10, 5);
466 PUTRATE(us, us1, uvmexp->pgswapin, PAGEROW + 3, PAGECOL + 5, 5); 474 PUTRATE(us, us1, uvmexp->pgswapin, PAGEROW + 3, PAGECOL + 5, 5);
467 PUTRATE(us, us1, uvmexp->pgswapout, PAGEROW + 3, PAGECOL + 10, 5); 475 PUTRATE(us, us1, uvmexp->pgswapout, PAGEROW + 3, PAGECOL + 10, 5);
468} 476}
469 477
470void 478void
471showvmstat(void) 479showvmstat(void)
472{ 480{
473 int inttotal; 481 int inttotal;
474 int i, l, r, c; 482 int i, l, r, c;
475 static int failcnt = 0; 483 static int failcnt = 0;
476 static int relabel = 0; 484 static int relabel = 0;
477 static int last_disks = 0; 485 static int last_disks = 0;
478 static char pigs[] = "pigs"; 486 static char pigs[] = "pigs";
 487 static u_long bufmem;
 488 struct buf_sysctl *buffers;
 489 int mib[6];
 490 size_t size;
 491 int extraslop = 0;
479 492
480 if (relabel) { 493 if (relabel) {
481 labelvmstat(); 494 labelvmstat();
482 relabel = 0; 495 relabel = 0;
483 } 496 }
484 497
485 cpuswap(); 498 cpuswap();
486 if (display_mode == TIME) { 499 if (display_mode == TIME) {
487 drvswap(); 500 drvswap();
488 etime = cur.cp_etime; 501 etime = cur.cp_etime;
489 /* < 5 ticks - ignore this trash */ 502 /* < 5 ticks - ignore this trash */
490 if ((etime * hertz) < 1.0) { 503 if ((etime * hertz) < 1.0) {
491 if (failcnt++ <= MAXFAIL) 504 if (failcnt++ <= MAXFAIL)
492 return; 505 return;
493 clear(); 506 clear();
494 mvprintw(2, 10, "The alternate system clock has died!"); 507 mvprintw(2, 10, "The alternate system clock has died!");
495 mvprintw(3, 10, "Reverting to ``pigs'' display."); 508 mvprintw(3, 10, "Reverting to ``pigs'' display.");
496 move(CMDLINE, 0); 509 move(CMDLINE, 0);
497 refresh(); 510 refresh();
498 failcnt = 0; 511 failcnt = 0;
499 sleep(5); 512 sleep(5);
500 command(pigs); 513 command(pigs);
501 return; 514 return;
502 } 515 }
503 } else 516 } else
504 etime = 1.0; 517 etime = 1.0;
505 518
506 show_vmstat_top(&s.Total, &s.uvmexp, &s1.uvmexp); 519 show_vmstat_top(&s.Total, &s.uvmexp, &s1.uvmexp);
507 520
508 /* Memory totals */ 521 /* Memory totals */
509#define pgtokb(pg) ((pg) * (s.uvmexp.pagesize / 1024)) 522#define pgtokb(pg) ((pg) * (s.uvmexp.pagesize / 1024))
510 putint(pgtokb(s.uvmexp.active), MEMROW + 2, MEMCOL + 6, 9); 523
511 putint(pgtokb(s.uvmexp.active + s.uvmexp.swpginuse), /* XXX */ 524 putint(pgtokb(s.uvmexp.anonpages), MEMROW + 0, MEMCOL + 7, 10);
512 MEMROW + 2, MEMCOL + 16, 9); 525 putint((s.uvmexp.anonpages * 100 + 0.5) / s.uvmexp.npages, MEMROW + 0, MEMCOL + 17, 4);
513 putint(pgtokb(s.uvmexp.npages - s.uvmexp.free), 526
514 MEMROW + 3, MEMCOL + 6, 9); 527 putint(pgtokb(s.uvmexp.zeropages), MEMROW + 0, MEMCOL + 30, 8);
515 putint(pgtokb(s.uvmexp.npages - s.uvmexp.free + s.uvmexp.swpginuse), 528
516 MEMROW + 3, MEMCOL + 16, 9); 529 putint(pgtokb(s.uvmexp.execpages), MEMROW + 1, MEMCOL + 7, 10);
517 putint(pgtokb(s.uvmexp.free), MEMROW + 2, MEMCOL + 26, 9); 530 putint((s.uvmexp.execpages * 100 + 0.5) / s.uvmexp.npages, MEMROW + 1, MEMCOL + 17, 4);
518 putint(pgtokb(s.uvmexp.free + s.uvmexp.swpages - s.uvmexp.swpginuse), 531
519 MEMROW + 3, MEMCOL + 26, 9); 532 putint(pgtokb(s.uvmexp.wired), MEMROW + 1, MEMCOL + 30, 8);
 533
 534 putint(pgtokb(s.uvmexp.filepages), MEMROW + 2, MEMCOL + 7, 10);
 535 putint((s.uvmexp.filepages * 100 + 0.5) / s.uvmexp.npages, MEMROW + 2, MEMCOL + 17, 4);
 536
 537 putint(pgtokb(s.uvmexp.inactive), MEMROW + 2, MEMCOL + 30, 8);
 538
 539 /* Get total size of metadata buffers */
 540 size = sizeof(bufmem);
 541 if (sysctlbyname("vm.bufmem", &bufmem, &size, NULL, 0) < 0) {
 542 error("can't get buffers size: %s\n", strerror(errno));
 543 return;
 544 }
 545
 546 /* Get number of metadata buffers */
 547 size = 0;
 548 buffers = NULL;
 549 mib[0] = CTL_KERN;
 550 mib[1] = KERN_BUF;
 551 mib[2] = KERN_BUF_ALL;
 552 mib[3] = KERN_BUF_ALL;
 553 mib[4] = (int)sizeof(struct buf_sysctl);
 554 mib[5] = INT_MAX; /* we want them all */
 555again:
 556 if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
 557 error("can't get buffers size: %s\n", strerror(errno));
 558 return;
 559 }
 560 if (size == 0) {
 561 error("buffers size is zero: %s\n", strerror(errno));
 562 return;
 563 }
 564 size += extraslop * sizeof(struct buf_sysctl);
 565 buffers = malloc(size);
 566 if (buffers == NULL) {
 567 error("can't allocate buffers: %s\n", strerror(errno));
 568 return;
 569 }
 570 if (sysctl(mib, 6, buffers, &size, NULL, 0) < 0) {
 571 free(buffers);
 572 if (extraslop == 0) {
 573 extraslop = 100;
 574 goto again;
 575 }
 576 error("can't get buffers: %s\n", strerror(errno));
 577 return;
 578 }
 579 free(buffers); /* XXX there must be a better way! */
 580 nbuf = size / sizeof(struct buf_sysctl);
 581
 582 putint((int) (bufmem / 1024), MEMROW + 3, MEMCOL + 5, 12);
 583 putint((int) ((bufmem * 100) + 0.5) / s.uvmexp.pagesize / s.uvmexp.npages,
 584 MEMROW + 3, MEMCOL + 17, 4);
 585 putint(nbuf, MEMROW + 3, MEMCOL + 30, 8);
 586
 587 putint(pgtokb(s.uvmexp.active), MEMROW + 5, MEMCOL + 7, 10);
 588 putint(pgtokb(s.uvmexp.swpgonly), MEMROW + 5, MEMCOL + 18, 10);
 589 putint(pgtokb(s.uvmexp.free), MEMROW + 5, MEMCOL + 28, 10);
 590
520#undef pgtokb 591#undef pgtokb
521 592
522 /* Namei cache */ 593 /* Namei cache */
523 Z(s, s1, ncs_goodhits); Z(s, s1, ncs_badhits); Z(s, s1, ncs_miss); 594 Z(s, s1, ncs_goodhits); Z(s, s1, ncs_badhits); Z(s, s1, ncs_miss);
524 Z(s, s1, ncs_long); Z(s, s1, ncs_pass2); Z(s, s1, ncs_2passes); 595 Z(s, s1, ncs_long); Z(s, s1, ncs_pass2); Z(s, s1, ncs_2passes);
525 s.nchcount = s.nchstats.ncs_goodhits + s.nchstats.ncs_badhits + 596 s.nchcount = s.nchstats.ncs_goodhits + s.nchstats.ncs_badhits +
526 s.nchstats.ncs_miss + s.nchstats.ncs_long + 597 s.nchstats.ncs_miss + s.nchstats.ncs_long +
527 s.nchstats.ncs_pass2 + s.nchstats.ncs_2passes; 598 s.nchstats.ncs_pass2 + s.nchstats.ncs_2passes;
528 if (display_mode == TIME) 599 if (display_mode == TIME)
529 s1.nchcount = s.nchcount; 600 s1.nchcount = s.nchcount;
530 601
531 putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9); 602 putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9);
532 putint(s.nchstats.ncs_goodhits, NAMEIROW + 2, NAMEICOL + 9, 9); 603 putint(s.nchstats.ncs_goodhits, NAMEIROW + 2, NAMEICOL + 9, 9);
533#define nz(x) ((x) ? (x) : 1) 604#define nz(x) ((x) ? (x) : 1)
534 putfloat(s.nchstats.ncs_goodhits * 100.0 / nz(s.nchcount), 605 putfloat(s.nchstats.ncs_goodhits * 100.0 / nz(s.nchcount),
535 NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1); 606 NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1);
536 putint(s.nchstats.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9); 607 putint(s.nchstats.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9);
537 putfloat(s.nchstats.ncs_pass2 * 100.0 / nz(s.nchcount), 608 putfloat(s.nchstats.ncs_pass2 * 100.0 / nz(s.nchcount),
538 NAMEIROW + 2, NAMEICOL + 34, 4, 0, 1); 609 NAMEIROW + 2, NAMEICOL + 34, 4, 0, 1);
539#undef nz 610#undef nz
540 611
541 /* Disks */ 612 /* Disks */
542 for (l = 0, i = 0, r = DISKROW, c = DISKCOL; 613 for (l = 0, i = 0, r = DISKROW, c = DISKCOL;
543 i < (int)ndrive; i++) { 614 i < (int)ndrive; i++) {
544 if (!drv_select[i]) 615 if (!drv_select[i])
545 continue; 616 continue;
546 617
547 if (disk_horiz) 618 if (disk_horiz)
548 c += DISKCOLWIDTH; 619 c += DISKCOLWIDTH;
549 else 620 else
550 r++; 621 r++;
551 if (c + DISKCOLWIDTH > DISKCOLEND) { 622 if (c + DISKCOLWIDTH > DISKCOLEND) {
552 if (disk_horiz && LINES - 1 - DISKROW > 623 if (disk_horiz && LINES - 1 - DISKROW >
553 (DISKCOLEND - DISKCOL) / DISKCOLWIDTH) { 624 (DISKCOLEND - DISKCOL) / DISKCOLWIDTH) {
554 disk_horiz = 0; 625 disk_horiz = 0;
555 relabel = 1; 626 relabel = 1;
556 } 627 }
557 break; 628 break;
558 } 629 }
559 if (r >= LINES - 1) { 630 if (r >= LINES - 1) {
560 if (!disk_horiz && LINES - 1 - DISKROW < 631 if (!disk_horiz && LINES - 1 - DISKROW <
561 (DISKCOLEND - DISKCOL) / DISKCOLWIDTH) { 632 (DISKCOLEND - DISKCOL) / DISKCOLWIDTH) {
562 disk_horiz = 1; 633 disk_horiz = 1;
563 relabel = 1; 634 relabel = 1;
564 } 635 }
565 break; 636 break;
566 } 637 }
567 l++; 638 l++;
568 639
569 dinfo(i, r, c); 640 dinfo(i, r, c);
570 } 641 }
571 /* blank out if we lost any disks */ 642 /* blank out if we lost any disks */
572 for (i = l; i < last_disks; i++) { 643 for (i = l; i < last_disks; i++) {
573 int j; 644 int j;
574 if (disk_horiz) 645 if (disk_horiz)
575 c += DISKCOLWIDTH; 646 c += DISKCOLWIDTH;
576 else 647 else
577 r++; 648 r++;
578 for (j = 0; j < 5; j++) { 649 for (j = 0; j < 5; j++) {
579 if (disk_horiz) 650 if (disk_horiz)
580 mvprintw(r+j, c, "%*s", DISKCOLWIDTH, ""); 651 mvprintw(r+j, c, "%*s", DISKCOLWIDTH, "");
581 else 652 else
582 mvprintw(r, c+j*DISKCOLWIDTH, "%*s", DISKCOLWIDTH, ""); 653 mvprintw(r, c+j*DISKCOLWIDTH, "%*s", DISKCOLWIDTH, "");
583 } 654 }
584 } 655 }
585 last_disks = l; 656 last_disks = l;
586 657
587 /* Interrupts */ 658 /* Interrupts */
588 failcnt = 0; 659 failcnt = 0;
589 inttotal = 0; 660 inttotal = 0;
590 for (i = 0; i < nintr; i++) { 661 for (i = 0; i < nintr; i++) {
591 if (s.intrcnt[i] == 0) 662 if (s.intrcnt[i] == 0)
592 continue; 663 continue;
593 if (intrloc[i] == 0) { 664 if (intrloc[i] == 0) {
594 if (nextintsrow == LINES) 665 if (nextintsrow == LINES)
595 continue; 666 continue;
596 intrloc[i] = nextintsrow++; 667 intrloc[i] = nextintsrow++;
597 mvprintw(intrloc[i], INTSCOL + 9, "%-.*s", 668 mvprintw(intrloc[i], INTSCOL + 9, "%-.*s",
598 INTSCOLEND - (INTSCOL + 9), intrname[i]); 669 INTSCOLEND - (INTSCOL + 9), intrname[i]);
599 } 670 }
600 X(s, s1, intrcnt); 671 X(s, s1, intrcnt);
601 l = (int)((float)s.intrcnt[i]/etime + 0.5); 672 l = (int)((float)s.intrcnt[i]/etime + 0.5);
602 inttotal += l; 673 inttotal += l;
603 putint(l, intrloc[i], INTSCOL, 8); 674 putint(l, intrloc[i], INTSCOL, 8);
604 } 675 }
605 676
606 for (i = 0; i < nevcnt; i++) { 677 for (i = 0; i < nevcnt; i++) {
607 if (s.evcnt[i] == 0) 678 if (s.evcnt[i] == 0)
608 continue; 679 continue;
609 if (ie_head[i].ie_loc == 0) { 680 if (ie_head[i].ie_loc == 0) {
610 if (nextintsrow == LINES) 681 if (nextintsrow == LINES)
611 continue; 682 continue;
612 ie_head[i].ie_loc = nextintsrow++; 683 ie_head[i].ie_loc = nextintsrow++;
613 print_ie_title(i); 684 print_ie_title(i);
614 } 685 }
615 X(s, s1, evcnt); 686 X(s, s1, evcnt);
616 l = (int)((float)s.evcnt[i]/etime + 0.5); 687 l = (int)((float)s.evcnt[i]/etime + 0.5);
617 inttotal += l; 688 inttotal += l;
618 putint(l, ie_head[i].ie_loc, INTSCOL, 8); 689 putint(l, ie_head[i].ie_loc, INTSCOL, 8);
619 } 690 }
620 putint(inttotal, INTSROW, INTSCOL, 8); 691 putint(inttotal, INTSROW, INTSCOL, 8);
621 692
622 PUTRATE(s, s1, uvmexp.forks, VMSTATROW + 0, VMSTATCOL + 3, 6); 693 PUTRATE(s, s1, uvmexp.forks, VMSTATROW + 0, VMSTATCOL + 3, 6);
623 PUTRATE(s, s1, uvmexp.forks_ppwait, VMSTATROW + 1, VMSTATCOL + 3, 6); 694 PUTRATE(s, s1, uvmexp.forks_ppwait, VMSTATROW + 1, VMSTATCOL + 3, 6);
624 PUTRATE(s, s1, uvmexp.forks_sharevm, VMSTATROW + 2, VMSTATCOL + 3, 6); 695 PUTRATE(s, s1, uvmexp.forks_sharevm, VMSTATROW + 2, VMSTATCOL + 3, 6);
625 PUTRATE(s, s1, uvmexp.fltpgwait, VMSTATROW + 3, VMSTATCOL + 4, 5); 696 PUTRATE(s, s1, uvmexp.fltpgwait, VMSTATROW + 3, VMSTATCOL + 4, 5);
626 PUTRATE(s, s1, uvmexp.fltrelck, VMSTATROW + 4, VMSTATCOL + 3, 6); 697 PUTRATE(s, s1, uvmexp.fltrelck, VMSTATROW + 4, VMSTATCOL + 3, 6);
627 PUTRATE(s, s1, uvmexp.fltrelckok, VMSTATROW + 5, VMSTATCOL + 3, 6); 698 PUTRATE(s, s1, uvmexp.fltrelckok, VMSTATROW + 5, VMSTATCOL + 3, 6);
628 PUTRATE(s, s1, uvmexp.fltnoram, VMSTATROW + 6, VMSTATCOL + 3, 6); 699 PUTRATE(s, s1, uvmexp.fltnoram, VMSTATROW + 6, VMSTATCOL + 3, 6);
629 PUTRATE(s, s1, uvmexp.fltamcopy, VMSTATROW + 7, VMSTATCOL + 3, 6); 700 PUTRATE(s, s1, uvmexp.fltamcopy, VMSTATROW + 7, VMSTATCOL + 3, 6);
630 PUTRATE(s, s1, uvmexp.flt_prcopy, VMSTATROW + 8, VMSTATCOL + 3, 6); 701 PUTRATE(s, s1, uvmexp.flt_prcopy, VMSTATROW + 8, VMSTATCOL + 3, 6);
631 PUTRATE(s, s1, uvmexp.flt_przero, VMSTATROW + 9, VMSTATCOL + 3, 6); 702 PUTRATE(s, s1, uvmexp.flt_przero, VMSTATROW + 9, VMSTATCOL + 3, 6);
632 PUTRATE(s, s1, uvmexp.flt_acow, VMSTATROW + 10, VMSTATCOL, 9); 703 PUTRATE(s, s1, uvmexp.flt_acow, VMSTATROW + 10, VMSTATCOL, 9);
633 putint(s.uvmexp.freemin, VMSTATROW + 11, VMSTATCOL, 9); 704 putint(s.uvmexp.freemin, VMSTATROW + 11, VMSTATCOL, 9);
634 putint(s.uvmexp.freetarg, VMSTATROW + 12, VMSTATCOL, 9); 705 putint(s.uvmexp.freetarg, VMSTATROW + 12, VMSTATCOL, 9);
635 putint(s.uvmexp.inactarg, VMSTATROW + 13, VMSTATCOL, 9); 706 putint(s.uvmexp.inactarg, VMSTATROW + 13, VMSTATCOL, 9);
636 putint(s.uvmexp.wired, VMSTATROW + 14, VMSTATCOL, 9); 707 putint(s.uvmexp.fltnoanon, VMSTATROW + 14, VMSTATCOL, 9);
637 PUTRATE(s, s1, uvmexp.pdfreed, VMSTATROW + 15, VMSTATCOL, 9); 708 PUTRATE(s, s1, uvmexp.pdfreed, VMSTATROW + 15, VMSTATCOL, 9);
638 if (LINES - 1 > VMSTATROW + 16) 709 if (LINES - 1 > VMSTATROW + 16)
639 PUTRATE(s, s1, uvmexp.pdscans, VMSTATROW + 16, VMSTATCOL, 9); 710 PUTRATE(s, s1, uvmexp.pdscans, VMSTATROW + 16, VMSTATCOL, 9);
640 711
641} 712}
642 713
643void 714void
644vmstat_boot(char *args) 715vmstat_boot(char *args)
645{ 716{
646 copyinfo(&z, &s1); 717 copyinfo(&z, &s1);
647 display_mode = BOOT; 718 display_mode = BOOT;
648} 719}
649 720
650void 721void
651vmstat_run(char *args) 722vmstat_run(char *args)
652{ 723{
653 copyinfo(&s1, &s2); 724 copyinfo(&s1, &s2);
654 display_mode = RUN; 725 display_mode = RUN;
655} 726}
656 727
657void 728void
658vmstat_time(char *args) 729vmstat_time(char *args)
659{ 730{
660 display_mode = TIME; 731 display_mode = TIME;
661} 732}
662 733
663void 734void
664vmstat_zero(char *args) 735vmstat_zero(char *args)
665{ 736{
666 if (display_mode == RUN) 737 if (display_mode == RUN)
667 getinfo(&s1); 738 getinfo(&s1);
668} 739}
669 740
670/* calculate number of users on the system */ 741/* calculate number of users on the system */
671static int 742static int
672ucount(void) 743ucount(void)
673{ 744{
674 static int onusers = -1; 745 static int onusers = -1;
675 int nusers = 0; 746 int nusers = 0;
676 struct utmpentry *ehead; 747 struct utmpentry *ehead;
677 748
678 nusers = getutentries(NULL, &ehead); 749 nusers = getutentries(NULL, &ehead);
679 750
680 if (nusers != onusers) { 751 if (nusers != onusers) {
681 if (nusers == 1) 752 if (nusers == 1)
682 mvprintw(STATROW, STATCOL + 8, " "); 753 mvprintw(STATROW, STATCOL + 8, " ");
683 else 754 else
684 mvprintw(STATROW, STATCOL + 8, "s"); 755 mvprintw(STATROW, STATCOL + 8, "s");
685 } 756 }
686 onusers = nusers; 757 onusers = nusers;
687 return (nusers); 758 return (nusers);
688} 759}
689 760
690static float 761static float
691cputime(int indx) 762cputime(int indx)
692{ 763{
693 double t; 764 double t;
694 int i; 765 int i;
695 766
696 t = 0; 767 t = 0;
697 for (i = 0; i < CPUSTATES; i++) 768 for (i = 0; i < CPUSTATES; i++)
698 t += cur.cp_time[i]; 769 t += cur.cp_time[i];
699 if (t == 0.0) 770 if (t == 0.0)
700 t = 1.0; 771 t = 1.0;
701 return (cur.cp_time[indx] * 100.0 / t); 772 return (cur.cp_time[indx] * 100.0 / t);
702} 773}
703 774
704void 775void
705puthumanint(u_int64_t n, int l, int c, int w) 776puthumanint(u_int64_t n, int l, int c, int w)
706{ 777{
707 char b[128]; 778 char b[128];
708 779
709 if (move(l, c) != OK) 780 if (move(l, c) != OK)
710 return; 781 return;
711 if (n == 0) { 782 if (n == 0) {
712 hline(' ', w); 783 hline(' ', w);
713 return; 784 return;
714 } 785 }
715 if (humanize_number(b, w, n, "", HN_AUTOSCALE, HN_NOSPACE) == -1 ) { 786 if (humanize_number(b, w, n, "", HN_AUTOSCALE, HN_NOSPACE) == -1 ) {
716 hline('*', w); 787 hline('*', w);
717 return; 788 return;
718 } 789 }
719 printw("%*s", w, b); 790 printw("%*s", w, b);
720} 791}
721 792
722void 793void
723putint(int n, int l, int c, int w) 794putint(int n, int l, int c, int w)
724{ 795{
725 char b[128]; 796 char b[128];
726 797
727 if (move(l, c) != OK) 798 if (move(l, c) != OK)
728 return; 799 return;
729 if (n == 0) { 800 if (n == 0) {
730 hline(' ', w); 801 hline(' ', w);
731 return; 802 return;
732 } 803 }
733 (void)snprintf(b, sizeof b, "%*d", w, n); 804 (void)snprintf(b, sizeof b, "%*d", w, n);
734 if ((int)strlen(b) > w) { 805 if ((int)strlen(b) > w) {
735 if (display_mode == TIME) 806 if (display_mode == TIME)
736 hline('*', w); 807 hline('*', w);
737 else 808 else
738 puthumanint(n, l, c, w); 809 puthumanint(n, l, c, w);
739 return; 810 return;
740 } 811 }
741 addstr(b); 812 addstr(b);
742} 813}
743 814
744void 815void
745putfloat(double f, int l, int c, int w, int d, int nz) 816putfloat(double f, int l, int c, int w, int d, int nz)
746{ 817{
747 char b[128]; 818 char b[128];
748 819
749 if (move(l, c) != OK) 820 if (move(l, c) != OK)
750 return; 821 return;
751 if (nz && f == 0.0) { 822 if (nz && f == 0.0) {
752 hline(' ', w); 823 hline(' ', w);
753 return; 824 return;
754 } 825 }
755 (void)snprintf(b, sizeof b, "%*.*f", w, d, f); 826 (void)snprintf(b, sizeof b, "%*.*f", w, d, f);
756 if ((int)strlen(b) > w) { 827 if ((int)strlen(b) > w) {
757 hline('*', w); 828 hline('*', w);
758 return; 829 return;
759 } 830 }
760 addstr(b); 831 addstr(b);
761} 832}
762 833
763static void 834static void
764getinfo(struct Info *stats) 835getinfo(struct Info *stats)
765{ 836{
766 int mib[2]; 837 int mib[2];
767 size_t size; 838 size_t size;
768 int i; 839 int i;
769 840
770 cpureadstats(); 841 cpureadstats();
771 drvreadstats(); 842 drvreadstats();
772 size = sizeof(stats->nchstats); 843 size = sizeof(stats->nchstats);
773 if (sysctlbyname("vfs.namecache_stats", &stats->nchstats, &size, 844 if (sysctlbyname("vfs.namecache_stats", &stats->nchstats, &size,
774 NULL, 0) < 0) { 845 NULL, 0) < 0) {
775 error("can't get namecache statistics: %s\n", strerror(errno)); 846 error("can't get namecache statistics: %s\n", strerror(errno));
776 memset(&stats->nchstats, 0, sizeof(stats->nchstats)); 847 memset(&stats->nchstats, 0, sizeof(stats->nchstats));
777 } 848 }
778 if (nintr) 849 if (nintr)
779 NREAD(X_INTRCNT, stats->intrcnt, nintr * LONG); 850 NREAD(X_INTRCNT, stats->intrcnt, nintr * sizeof(long));
780 for (i = 0; i < nevcnt; i++) 851 for (i = 0; i < nevcnt; i++)
781 KREAD(ie_head[i].ie_count, &stats->evcnt[i], 852 KREAD(ie_head[i].ie_count, &stats->evcnt[i],
782 sizeof stats->evcnt[i]); 853 sizeof stats->evcnt[i]);
783 size = sizeof(stats->uvmexp); 854 size = sizeof(stats->uvmexp);
784 mib[0] = CTL_VM; 855 mib[0] = CTL_VM;
785 mib[1] = VM_UVMEXP2; 856 mib[1] = VM_UVMEXP2;
786 if (sysctl(mib, 2, &stats->uvmexp, &size, NULL, 0) < 0) { 857 if (sysctl(mib, 2, &stats->uvmexp, &size, NULL, 0) < 0) {
787 error("can't get uvmexp: %s\n", strerror(errno)); 858 error("can't get uvmexp: %s\n", strerror(errno));
788 memset(&stats->uvmexp, 0, sizeof(stats->uvmexp)); 859 memset(&stats->uvmexp, 0, sizeof(stats->uvmexp));
789 } 860 }
790 size = sizeof(stats->Total); 861 size = sizeof(stats->Total);
791 mib[0] = CTL_VM; 862 mib[0] = CTL_VM;
792 mib[1] = VM_METER; 863 mib[1] = VM_METER;
793 if (sysctl(mib, 2, &stats->Total, &size, NULL, 0) < 0) { 864 if (sysctl(mib, 2, &stats->Total, &size, NULL, 0) < 0) {
794 error("Can't get kernel info: %s\n", strerror(errno)); 865 error("Can't get kernel info: %s\n", strerror(errno));
795 memset(&stats->Total, 0, sizeof(stats->Total)); 866 memset(&stats->Total, 0, sizeof(stats->Total));
796 } 867 }
797} 868}
798 869
799static void 870static void
800allocinfo(struct Info *stats) 871allocinfo(struct Info *stats)
801{ 872{
802 873
803 if (nintr && 874 if (nintr &&
804 (stats->intrcnt = calloc(nintr, sizeof(long))) == NULL) { 875 (stats->intrcnt = calloc(nintr, sizeof(long))) == NULL) {
805 error("calloc failed"); 876 error("calloc failed");
806 die(0); 877 die(0);
807 } 878 }
808 if ((stats->evcnt = calloc(nevcnt, sizeof(u_int64_t))) == NULL) { 879 if ((stats->evcnt = calloc(nevcnt, sizeof(u_int64_t))) == NULL) {
809 error("calloc failed"); 880 error("calloc failed");
810 die(0); 881 die(0);
811 } 882 }
812} 883}
813 884
814static void 885static void
815copyinfo(struct Info *from, struct Info *to) 886copyinfo(struct Info *from, struct Info *to)
816{ 887{
817 long *intrcnt; 888 long *intrcnt;
818 u_int64_t *evcnt; 889 u_int64_t *evcnt;
819 890
820 intrcnt = to->intrcnt; 891 intrcnt = to->intrcnt;
821 evcnt = to->evcnt; 892 evcnt = to->evcnt;
822 *to = *from; 893 *to = *from;
823 memmove(to->intrcnt = intrcnt, from->intrcnt, nintr * sizeof *intrcnt); 894 memmove(to->intrcnt = intrcnt, from->intrcnt, nintr * sizeof *intrcnt);
824 memmove(to->evcnt = evcnt, from->evcnt, nevcnt * sizeof *evcnt); 895 memmove(to->evcnt = evcnt, from->evcnt, nevcnt * sizeof *evcnt);
825} 896}
826 897
827static void 898static void
828dinfo(int dn, int r, int c) 899dinfo(int dn, int r, int c)
829{ 900{
830 double atime, dtime; 901 double atime, dtime;
831#define ADV if (disk_horiz) r++; else c += DISKCOLWIDTH 902#define ADV if (disk_horiz) r++; else c += DISKCOLWIDTH
832 903
833 /* elapsed time for disk stats */ 904 /* elapsed time for disk stats */
834 dtime = etime; 905 dtime = etime;
835 if (cur.timestamp[dn].tv_sec || cur.timestamp[dn].tv_usec) { 906 if (cur.timestamp[dn].tv_sec || cur.timestamp[dn].tv_usec) {
836 dtime = (double)cur.timestamp[dn].tv_sec + 907 dtime = (double)cur.timestamp[dn].tv_sec +
837 ((double)cur.timestamp[dn].tv_usec / (double)1000000); 908 ((double)cur.timestamp[dn].tv_usec / (double)1000000);
838 } 909 }
839 910
840 mvprintw(r, c, "%*.*s", DISKCOLWIDTH, DISKCOLWIDTH, dr_name[dn]); 911 mvprintw(r, c, "%*.*s", DISKCOLWIDTH, DISKCOLWIDTH, dr_name[dn]);
841 ADV; 912 ADV;
842 913
843 putint((int)(cur.seek[dn]/dtime+0.5), r, c, DISKCOLWIDTH); 914 putint((int)(cur.seek[dn]/dtime+0.5), r, c, DISKCOLWIDTH);
844 ADV; 915 ADV;
845 putint((int)((cur.rxfer[dn]+cur.wxfer[dn])/dtime+0.5), 916 putint((int)((cur.rxfer[dn]+cur.wxfer[dn])/dtime+0.5),
846 r, c, DISKCOLWIDTH); 917 r, c, DISKCOLWIDTH);
847 ADV; 918 ADV;
848 puthumanint((cur.rbytes[dn] + cur.wbytes[dn]) / dtime + 0.5, 919 puthumanint((cur.rbytes[dn] + cur.wbytes[dn]) / dtime + 0.5,
849 r, c, DISKCOLWIDTH); 920 r, c, DISKCOLWIDTH);
850 ADV; 921 ADV;
851 922
852 /* time busy in disk activity */ 923 /* time busy in disk activity */
853 atime = cur.time[dn].tv_sec + cur.time[dn].tv_usec / 1000000.0; 924 atime = cur.time[dn].tv_sec + cur.time[dn].tv_usec / 1000000.0;
854 atime = atime * 100.0 / dtime; 925 atime = atime * 100.0 / dtime;
855 if (atime >= 100) 926 if (atime >= 100)
856 putint(100, r, c, DISKCOLWIDTH); 927 putint(100, r, c, DISKCOLWIDTH);
857 else 928 else
858 putfloat(atime, r, c, DISKCOLWIDTH, 1, 1); 929 putfloat(atime, r, c, DISKCOLWIDTH, 1, 1);
859} 930}