Extend "systat vm" output to provide better insight about buffercache and document it. From Greg A. Woods in PR bin/36542diff -r1.28 -r1.29 src/usr.bin/systat/bufcache.c
(sevan)
--- 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 | |||
63 | struct vcache { | 63 | struct 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 | |||
69 | struct ml_entry { | 69 | struct 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 | |||
78 | static struct vcache vcache[VCACHE_SIZE]; | 78 | static struct vcache vcache[VCACHE_SIZE]; | |
79 | static LIST_HEAD(mount_list, ml_entry) mount_list; | 79 | static LIST_HEAD(mount_list, ml_entry) mount_list; | |
80 | 80 | |||
81 | static uint64_t bufmem; | 81 | static uint64_t bufmem; | |
82 | static u_int nbuf, pgwidth, kbwidth; | 82 | static u_int nbuf, pgwidth, kbwidth; | |
83 | static struct uvmexp_sysctl uvmexp; | 83 | static struct uvmexp_sysctl uvmexp; | |
84 | 84 | |||
85 | static void vc_init(void); | 85 | static void vc_init(void); | |
86 | static void ml_init(void); | 86 | static void ml_init(void); | |
87 | static struct vnode *vc_lookup(struct vnode *); | 87 | static struct vnode *vc_lookup(struct vnode *); | |
88 | static struct mount *ml_lookup(struct mount *, int, int); | 88 | static struct mount *ml_lookup(struct mount *, int, int); | |
89 | static void fetchuvmexp(void); | 89 | static void fetchuvmexp(void); | |
90 | 90 | |||
91 | 91 | |||
92 | WINDOW * | 92 | WINDOW * | |
93 | openbufcache(void) | 93 | openbufcache(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 | |||
99 | void | 99 | void | |
100 | closebufcache(WINDOW *w) | 100 | closebufcache(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 | |||
111 | void | 111 | void | |
112 | labelbufcache(void) | 112 | labelbufcache(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 | |||
125 | void | 125 | void | |
126 | showbufcache(void) | 126 | showbufcache(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 | |||
223 | int | 223 | int | |
224 | initbufcache(void) | 224 | initbufcache(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 | |||
234 | static void | 234 | static void | |
235 | fetchuvmexp(void) | 235 | fetchuvmexp(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 | |||
250 | void | 250 | void | |
251 | fetchbufcache(void) | 251 | fetchbufcache(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 */ | |
277 | again: | 277 | again: | |
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 | |||
353 | static void | 353 | static void | |
354 | vc_init(void) | 354 | vc_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 | |||
363 | static void | 363 | static void | |
364 | ml_init(void) | 364 | ml_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 | |||
376 | static struct vnode * | 376 | static struct vnode * | |
377 | vc_lookup(struct vnode *vaddr) | 377 | vc_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 | |||
413 | static struct mount * | 413 | static struct mount * | |
414 | ml_lookup(struct mount *maddr, int size, int valid) | 414 | ml_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 | } |
--- 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 | |
35 | static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93"; | 35 | static 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 | |||
48 | struct command global_commands[] = { | 48 | struct 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 | |||
58 | struct command df_commands[] = { | 59 | struct 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 | |||
64 | struct command icmp_commands[] = { | 65 | struct 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 | |||
72 | struct command ifstat_commands[] = { | 73 | struct 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 | |||
79 | struct command iostat_commands[] = { | 80 | struct 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 | |||
92 | struct command ip_commands[] = { | 93 | struct 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 | |
101 | struct command ip6_commands[] = { | 102 | struct 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 | |||
110 | struct command netstat_commands[] = { | 111 | struct 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 | |||
123 | struct command ps_commands[] = { | 124 | struct 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 | |||
128 | struct command tcp_commands[] = { | 129 | struct 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 | |||
136 | struct command vmstat_commands[] = { | 137 | struct 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 | |||
148 | struct command syscall_commands[] = { | 149 | struct 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 | |||
158 | struct mode modes[] = { | 159 | struct 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 | }; | |
212 | struct mode *curmode = &modes[0]; | 213 | struct mode *curmode = &modes[0]; |
--- 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 | |
37 | static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; | 37 | static 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 | |||
61 | static int dellave; | 61 | static int dellave; | |
62 | 62 | |||
63 | kvm_t *kd; | 63 | kvm_t *kd; | |
64 | char *memf = NULL; | 64 | char *memf = NULL; | |
65 | char *nlistf = NULL; | 65 | char *nlistf = NULL; | |
66 | sig_t sigtstpdfl; | 66 | sig_t sigtstpdfl; | |
67 | double avenrun[3]; | 67 | double avenrun[3]; | |
68 | int col; | 68 | int col; | |
69 | double naptime = 5; | 69 | double naptime = 1; | |
70 | int verbose = 1; /* to report kvm read errs */ | 70 | int verbose = 1; /* to report kvm read errs */ | |
71 | int hz, stathz, maxslp; | 71 | int hz, stathz, maxslp; | |
72 | char c; | 72 | char c; | |
73 | char *namp; | 73 | char *namp; | |
74 | char hostname[MAXHOSTNAMELEN + 1]; | 74 | char hostname[MAXHOSTNAMELEN + 1]; | |
75 | WINDOW *wnd; | 75 | WINDOW *wnd; | |
76 | int CMDLINE; | 76 | int CMDLINE; | |
77 | int turns = 2; /* stay how many refresh-turns in 'all' mode? */ | 77 | int turns = 2; /* stay how many refresh-turns in 'all' mode? */ | |
78 | int allflag; | 78 | int allflag; | |
79 | int allcounter; | 79 | int allcounter; | |
80 | sig_atomic_t needsredraw = 0; | 80 | sig_atomic_t needsredraw = 0; | |
81 | 81 | |||
82 | static WINDOW *wload; /* one line window for load average */ | 82 | static WINDOW *wload; /* one line window for load average */ | |
83 | 83 | |||
84 | static void (*sv_stop_handler)(int); | 84 | static void (*sv_stop_handler)(int); | |
85 | 85 | |||
86 | static void stop(int); | 86 | static void stop(int); | |
87 | __dead static void usage(void); | 87 | __dead static void usage(void); | |
88 | 88 | |||
89 | gid_t egid; /* XXX needed by initiostat() and initkre() */ | 89 | gid_t egid; /* XXX needed by initiostat() and initkre() */ | |
90 | 90 | |||
91 | int | 91 | int | |
92 | main(int argc, char **argv) | 92 | main(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 | |||
242 | static void | 245 | static void | |
243 | usage(void) | 246 | usage(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 | |||
251 | void | 254 | void | |
252 | labels(void) | 255 | labels(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 | |||
266 | void | 269 | void | |
267 | display(int signo) | 270 | display(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 | |||
329 | void | 332 | void | |
330 | redraw(void) | 333 | redraw(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 | |||
340 | static void | 343 | static void | |
341 | stop(int signo) | 344 | stop(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 | |||
357 | void | 360 | void | |
358 | die(int signo) | 361 | die(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 | |||
367 | void | 370 | void | |
368 | error(const char *fmt, ...) | 371 | error(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 | |||
392 | void | 395 | void | |
393 | clearerror(void) | 396 | clearerror(void) | |
394 | { | 397 | { | |
395 | 398 | |||
396 | error("%s", ""); | 399 | error("%s", ""); | |
397 | } | 400 | } | |
398 | 401 | |||
399 | void | 402 | void | |
400 | nlisterr(struct nlist name_list[]) | 403 | nlisterr(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 | } |
--- 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 | |
49 | displays various system statistics in a screen oriented fashion | 49 | displays various system statistics in a screen oriented fashion | |
50 | using the curses screen display library, | 50 | using the curses screen display library, | |
51 | .Xr curses 3 . | 51 | .Xr curses 3 . | |
52 | .Pp | 52 | .Pp | |
53 | While | 53 | While | |
54 | .Nm | 54 | .Nm | |
55 | is running the screen is usually divided into two windows (an exception | 55 | is running the screen is usually divided into two windows (an exception | |
56 | is the vmstat display which uses the entire screen). | 56 | is the vmstat display which uses the entire screen). | |
57 | The upper window depicts the current system load average. | 57 | The upper window depicts the current system load average. | |
58 | The information displayed in the lower window may vary, depending on | 58 | The information displayed in the lower window may vary, depending on | |
59 | user commands. | 59 | user commands. | |
60 | The last line on the screen is reserved for user input and error messages. | 60 | The last line on the screen is reserved for user input and error messages. | |
61 | .Pp | 61 | .Pp | |
62 | By default | 62 | By default | |
63 | .Nm | 63 | .Nm | |
64 | displays the processes getting the largest percentage of the processor | 64 | displays the processes getting the largest percentage of the processor | |
65 | in the lower window. | 65 | in the lower window. | |
66 | Other displays show more detailed process information, | 66 | Other displays show more detailed process information, | |
67 | swap space usage, | 67 | swap space usage, | |
68 | disk usage statistics (a la | 68 | disk usage statistics (a la | |
69 | .Xr df 1 ) , | 69 | .Xr df 1 ) , | |
70 | disk | 70 | disk | |
71 | .Tn I/O | 71 | .Tn I/O | |
72 | statistics (a la | 72 | statistics (a la | |
73 | .Xr iostat 8 ) , | 73 | .Xr iostat 8 ) , | |
74 | virtual memory statistics (a la | 74 | virtual memory statistics (a la | |
75 | .Xr vmstat 1 ) , | 75 | .Xr vmstat 1 ) , | |
76 | network ``mbuf'' utilization, network 'ifstat' traffic, and network connections (a la | 76 | network ``mbuf'' utilization, network 'ifstat' traffic, and network connections (a la | |
77 | .Xr netstat 1 ) . | 77 | .Xr netstat 1 ) . | |
78 | .Pp | 78 | .Pp | |
79 | Input is interpreted at two different levels. | 79 | Input is interpreted at two different levels. | |
80 | A ``global'' command interpreter processes all keyboard input. | 80 | A ``global'' command interpreter processes all keyboard input. | |
81 | If this command interpreter fails to recognize a command, the | 81 | If this command interpreter fails to recognize a command, the | |
82 | input line is passed to a per-display command interpreter. | 82 | input line is passed to a per-display command interpreter. | |
83 | This allows each display to have certain display-specific commands. | 83 | This allows each display to have certain display-specific commands. | |
84 | .Pp | 84 | .Pp | |
85 | Command line options: | 85 | Command 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 | |
88 | Extract values associated with the name list from | 88 | Extract values associated with the name list from | |
89 | .Ar core | 89 | .Ar core | |
90 | instead of the default | 90 | instead of the default | |
91 | .Pa /dev/mem . | 91 | .Pa /dev/mem . | |
92 | .It Fl N Ar system | 92 | .It Fl N Ar system | |
93 | Extract the name list from | 93 | Extract the name list from | |
94 | .Ar system | 94 | .Ar system | |
95 | instead of the default | 95 | instead of the default | |
96 | .Pa /netbsd . | 96 | .Pa /netbsd . | |
97 | .It Fl b | 97 | .It Fl b | |
98 | Show the chosen display once and exit. | 98 | Show the chosen display once and exit. | |
99 | .It Fl n | 99 | .It Fl n | |
100 | Do not resolve IP addresses into string hostnames | 100 | Do not resolve IP addresses into string hostnames | |
101 | .Pq FQDNs | 101 | .Pq FQDNs | |
102 | on | 102 | on | |
103 | .Ic netstat . | 103 | .Ic netstat . | |
104 | It has the same effect as | 104 | It has the same effect as | |
105 | .Ic numbers | 105 | .Ic numbers | |
106 | subcommand in | 106 | subcommand in | |
107 | .Ic netstat . | 107 | .Ic netstat . | |
108 | .It Fl w Ar wait | 108 | .It Fl w Ar wait | |
109 | See | 109 | See | |
110 | .Ar refresh-interval . | 110 | .Ar refresh-interval . | |
111 | .It Fl t Ar turns | 111 | .It Fl t Ar turns | |
112 | How many refreshes to show each screen in 'all' display mode. | 112 | How many refreshes to show each screen in 'all' display mode. | |
113 | .It Ar display | 113 | .It Ar display | |
114 | The | 114 | The | |
115 | .Ar display | 115 | .Ar display | |
116 | argument expects to be one of: | 116 | argument 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 | |
133 | or | 133 | or | |
134 | .Ic vmstat . | 134 | .Ic vmstat . | |
135 | These displays can also be requested interactively and are described in | 135 | These displays can also be requested interactively and are described in | |
136 | full detail below. | 136 | full detail below. | |
137 | .It Ar refresh-interval | 137 | .It Ar refresh-interval | |
138 | The | 138 | The | |
139 | .Ar refresh-interval | 139 | .Ar refresh-interval | |
140 | specifies the screen refresh time interval in seconds. | 140 | specifies the screen refresh time interval in seconds. | |
141 | This is provided for backwards compatibility, and overrides the | 141 | This is provided for backwards compatibility, and overrides the | |
142 | .Ar refresh-interval | 142 | .Ar refresh-interval | |
143 | specified with the | 143 | specified with the | |
144 | .Fl w | 144 | .Fl w | |
145 | flag. | 145 | flag. | |
146 | .El | 146 | .El | |
147 | .Pp | 147 | .Pp | |
148 | Certain characters cause immediate action by | 148 | Certain characters cause immediate action by | |
149 | .Nm . | 149 | .Nm . | |
150 | These are | 150 | These are | |
151 | .Bl -tag -width Fl | 151 | .Bl -tag -width Fl | |
152 | .It Ic \&^L | 152 | .It Ic \&^L | |
153 | Refresh the screen. | 153 | Refresh the screen. | |
154 | .It Ic \&^G | 154 | .It Ic \&^G | |
155 | Print the name of the current ``display'' being shown in | 155 | Print the name of the current ``display'' being shown in | |
156 | the lower window and the refresh interval. | 156 | the lower window and the refresh interval. | |
157 | .It Ic \&^Z | 157 | .It Ic \&^Z | |
158 | Stop | 158 | Stop | |
159 | .Nm . | 159 | .Nm . | |
160 | .It Ic \&? , Ic h | 160 | .It Ic \&? , Ic h | |
161 | Print the names of the available displays on the command line. | 161 | Print the names of the available displays on the command line. | |
162 | .It Ic \&: | 162 | .It Ic \&: | |
163 | Move the cursor to the command line and interpret the input | 163 | Move the cursor to the command line and interpret the input | |
164 | line typed as a command. | 164 | line typed as a command. | |
165 | While entering a command the current character erase, word erase, | 165 | While entering a command the current character erase, word erase, | |
166 | and line kill characters may be used. | 166 | and line kill characters may be used. | |
167 | .El | 167 | .El | |
168 | .Pp | 168 | .Pp | |
169 | The following commands are interpreted by the ``global'' | 169 | The following commands are interpreted by the ``global'' | |
170 | command interpreter. | 170 | command interpreter. | |
171 | .Bl -tag -width Fl | 171 | .Bl -tag -width Fl | |
172 | .It Ic help Ar key | 172 | .It Ic help Ar key | |
173 | Print the names of the available displays on the command line. | 173 | Print the names of the available displays on the command line. | |
174 | It will print long names as | 174 | It will print long names as | |
175 | .Dq Ic inet.* . | 175 | .Dq Ic inet.* . | |
176 | To print items under | 176 | To print items under | |
177 | .Dq Ic inet , | 177 | .Dq Ic inet , | |
178 | give | 178 | give | |
179 | .Ic inet | 179 | .Ic inet | |
180 | as | 180 | as | |
181 | .Ar key . | 181 | .Ar key . | |
182 | .It Ic load | 182 | .It Ic load | |
183 | Print the load average over the past 1, 5, and 15 minutes | 183 | Print the load average over the past 1, 5, and 15 minutes | |
184 | on the command line. | 184 | on the command line. | |
185 | .It Ic stop | 185 | .It Ic stop | |
186 | Stop refreshing the screen. | 186 | Stop refreshing the screen. | |
187 | .It Oo Ic start Oc Oo Ar number Oc | 187 | .It Oo Ic start Oc Oo Ar number Oc | |
188 | Start (continue) refreshing the screen. | 188 | Start (continue) refreshing the screen. | |
189 | If a second, numeric, argument is provided it is interpreted as a | 189 | If a second, numeric, argument is provided it is interpreted as a | |
190 | refresh interval in seconds. | 190 | refresh interval in seconds. | |
191 | Supplying only a number will set the refresh interval to this | 191 | Supplying only a number will set the refresh interval to this | |
192 | value. | 192 | value. | |
193 | .It Ic quit | 193 | .It Ic quit | |
194 | Exit | 194 | Exit | |
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 | |
200 | The available displays are: | 200 | The available displays are: | |
201 | .Bl -tag -width Ic | 201 | .Bl -tag -width Ic | |
202 | .It Ic all | 202 | .It Ic all | |
203 | Cycle through all displays automatically. | 203 | Cycle through all displays automatically. | |
204 | At each display, wait some | 204 | At each display, wait some | |
205 | refresh-turns, then switch to the next display. | 205 | refresh-turns, then switch to the next display. | |
206 | Duration of one refresh-turn is adjustable with the | 206 | Duration of one refresh-turn is adjustable with the | |
207 | .Fl w | 207 | .Fl w | |
208 | option, number of refresh-turns can be changed with the | 208 | option, number of refresh-turns can be changed with the | |
209 | .Fl t | 209 | .Fl t | |
210 | option. | 210 | option. | |
211 | .It Ic bufcache | 211 | .It Ic bufcache | |
212 | Display, in the lower window, statistics about the file system buffers. | 212 | Display, in the lower window, statistics about the file system buffers. | |
213 | Statistics for each file system that has active buffers include the number | 213 | Statistics for each file system that has active buffers include the number | |
214 | of buffers for that file system, the number of active kilobytes in those | 214 | of buffers for that file system, the number of active kilobytes in those | |
215 | buffers and the total size of the buffers for that file system. | 215 | buffers and the total size of the buffers for that file system. | |
216 | .It Ic df | 216 | .It Ic df | |
217 | Lists disk usage statistics for all filesystems, | 217 | Lists disk usage statistics for all filesystems, | |
218 | including the available free space as well as a bar | 218 | including the available free space as well as a bar | |
219 | graph indicating the used capacity. | 219 | graph indicating the used capacity. | |
220 | .Pp | 220 | .Pp | |
221 | The following commands are specific to the | 221 | The following commands are specific to the | |
222 | .Ic df | 222 | .Ic df | |
223 | display: | 223 | display: | |
224 | .Pp | 224 | .Pp | |
225 | .Bl -tag -width Fl -compact | 225 | .Bl -tag -width Fl -compact | |
226 | .It Cm all | 226 | .It Cm all | |
227 | Displays information for all filesystems, including | 227 | Displays information for all filesystems, including | |
228 | kernfs, procfs and null-mounts. | 228 | kernfs, procfs and null-mounts. | |
229 | .It Cm some | 229 | .It Cm some | |
230 | Suppress information about procfs, kernfs and null-mounts (default). | 230 | Suppress information about procfs, kernfs and null-mounts (default). | |
231 | .El | 231 | .El | |
232 | .It Ic ifstat | 232 | .It Ic ifstat | |
233 | Display the network traffic going through active interfaces on the | 233 | Display the network traffic going through active interfaces on the | |
234 | system. | 234 | system. | |
235 | Idle interfaces will not be displayed until they receive some | 235 | Idle interfaces will not be displayed until they receive some | |
236 | traffic. | 236 | traffic. | |
237 | .Pp | 237 | .Pp | |
238 | For each interface being displayed, the current, peak and total | 238 | For each interface being displayed, the current, peak and total | |
239 | statistics are displayed for incoming and outgoing traffic. | 239 | statistics are displayed for incoming and outgoing traffic. | |
240 | By default, | 240 | By default, | |
241 | the | 241 | the | |
242 | .Ic ifstat | 242 | .Ic ifstat | |
243 | display will automatically scale the units being used so that they are | 243 | display will automatically scale the units being used so that they are | |
244 | in a human-readable format. | 244 | in a human-readable format. | |
245 | The scaling units used for the current and | 245 | The scaling units used for the current and | |
246 | peak | 246 | peak | |
247 | traffic columns can be altered by the | 247 | traffic columns can be altered by the | |
248 | .Ic scale | 248 | .Ic scale | |
249 | command. | 249 | command. | |
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 | |
252 | Modify the scale used to display the current and peak traffic over all | 252 | Modify the scale used to display the current and peak traffic over all | |
253 | interfaces. | 253 | interfaces. | |
254 | The following units are recognised: kbit, kbyte, mbit, | 254 | The following units are recognised: kbit, kbyte, mbit, | |
255 | mbyte, gbit, gbyte and auto. | 255 | mbyte, gbit, gbyte and auto. | |
256 | .It Cm pps | 256 | .It Cm pps | |
257 | Show statistics in packets per second instead of bytes/bits per second. | 257 | Show statistics in packets per second instead of bytes/bits per second. | |
258 | A subsequent call of | 258 | A subsequent call of | |
259 | .Ic pps | 259 | .Ic pps | |
260 | switches this mode off. | 260 | switches this mode off. | |
261 | .It Cm match Op Ar patterns | 261 | .It Cm match Op Ar patterns | |
262 | Display only interfaces that match pattern provided as an argument. | 262 | Display only interfaces that match pattern provided as an argument. | |
263 | Patterns should be in shell syntax separated by whitespaces or commas. | 263 | Patterns should be in shell syntax separated by whitespaces or commas. | |
264 | If this command is called without arguments then all interfaces are displayed. | 264 | If this command is called without arguments then all interfaces are displayed. | |
265 | For example: | 265 | For example: | |
266 | .Pp | 266 | .Pp | |
267 | .Dl match re0, bge1 | 267 | .Dl match re0, bge1 | |
268 | .Pp | 268 | .Pp | |
269 | This will display re0 and bge1 interfaces. | 269 | This 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 | |
273 | This will display all | 273 | This will display all | |
274 | .Ic re | 274 | .Ic re | |
275 | interfaces, all | 275 | interfaces, all | |
276 | .Ic bge | 276 | .Ic bge | |
277 | interfaces and the loopback interface. | 277 | interfaces and the loopback interface. | |
278 | .El | 278 | .El | |
279 | .Pp | 279 | .Pp | |
280 | .It Ic inet.icmp | 280 | .It Ic inet.icmp | |
281 | Display ICMP statistics. | 281 | Display ICMP statistics. | |
282 | .It Ic inet.ip | 282 | .It Ic inet.ip | |
283 | Display IPv4 and UDP statistics. | 283 | Display IPv4 and UDP statistics. | |
284 | .It Ic inet.tcp | 284 | .It Ic inet.tcp | |
285 | Display TCP statistics. | 285 | Display TCP statistics. | |
286 | .It Ic inet.tcpsyn | 286 | .It Ic inet.tcpsyn | |
287 | Display statistics about the | 287 | Display statistics about the | |
288 | .Tn TCP | 288 | .Tn TCP | |
289 | ``syncache''. | 289 | ``syncache''. | |
290 | .It Ic inet6.ip6 | 290 | .It Ic inet6.ip6 | |
291 | Display IPv6 statistics. | 291 | Display IPv6 statistics. | |
292 | .It Ic iostat | 292 | .It Ic iostat | |
293 | Display, in the lower window, statistics about processor use | 293 | Display, in the lower window, statistics about processor use | |
294 | and disk throughput. | 294 | and disk throughput. | |
295 | Statistics on processor use appear as bar graphs of the amount of | 295 | Statistics on processor use appear as bar graphs of the amount of | |
296 | time executing in user mode (``user''), in user mode running low | 296 | time executing in user mode (``user''), in user mode running low | |
297 | priority processes (``nice''), in system mode (``system''), and | 297 | priority processes (``nice''), in system mode (``system''), and | |
298 | idle (``idle''). | 298 | idle (``idle''). | |
299 | Statistics on disk throughput show, for each drive, kilobytes of | 299 | Statistics on disk throughput show, for each drive, kilobytes of | |
300 | data transferred, number of disk transactions performed, and time | 300 | data transferred, number of disk transactions performed, and time | |
301 | spent in disk accesses in milliseconds. | 301 | spent in disk accesses in milliseconds. | |
302 | This information may be displayed as bar graphs or as rows of | 302 | This information may be displayed as bar graphs or as rows of | |
303 | numbers which scroll downward. | 303 | numbers which scroll downward. | |
304 | Bar graphs are shown by default; | 304 | Bar graphs are shown by default; | |
305 | .Pp | 305 | .Pp | |
306 | The following commands are specific to the | 306 | The following commands are specific to the | |
307 | .Ic iostat | 307 | .Ic iostat | |
308 | display; the minimum unambiguous prefix may be supplied. | 308 | display; 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 | |
312 | Show the disk | 312 | Show the disk | |
313 | .Tn I/O | 313 | .Tn I/O | |
314 | statistics in numeric form. | 314 | statistics in numeric form. | |
315 | Values are | 315 | Values are | |
316 | displayed in numeric columns which scroll downward. | 316 | displayed in numeric columns which scroll downward. | |
317 | .It Cm bars | 317 | .It Cm bars | |
318 | Show the disk | 318 | Show the disk | |
319 | .Tn I/O | 319 | .Tn I/O | |
320 | statistics in bar graph form (default). | 320 | statistics in bar graph form (default). | |
321 | .It Cm secs | 321 | .It Cm secs | |
322 | Toggle the display of time in disk activity (the default is to | 322 | Toggle the display of time in disk activity (the default is to | |
323 | not display time). | 323 | not display time). | |
324 | .It Cm all | 324 | .It Cm all | |
325 | Show the read and write statistics combined (default). | 325 | Show the read and write statistics combined (default). | |
326 | .It Cm rw | 326 | .It Cm rw | |
327 | Show the read and write statistics separately. | 327 | Show the read and write statistics separately. | |
328 | .El | 328 | .El | |
329 | .It Ic mbufs | 329 | .It Ic mbufs | |
330 | Display, in the lower window, the number of mbufs allocated | 330 | Display, in the lower window, the number of mbufs allocated | |
331 | for particular uses, i.e. data, socket structures, etc. | 331 | for particular uses, i.e. data, socket structures, etc. | |
332 | .It Ic netstat | 332 | .It Ic netstat | |
333 | Display, in the lower window, network connections. | 333 | Display, in the lower window, network connections. | |
334 | By default, network servers awaiting requests are not displayed. | 334 | By default, network servers awaiting requests are not displayed. | |
335 | Each address is displayed in the format ``host.port'', with each | 335 | Each address is displayed in the format ``host.port'', with each | |
336 | shown symbolically, when possible. | 336 | shown symbolically, when possible. | |
337 | It is possible to have addresses displayed numerically, | 337 | It is possible to have addresses displayed numerically, | |
338 | limit the display to a set of ports, hosts, and/or protocols | 338 | limit 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 | |
343 | Toggle the displaying of server processes awaiting requests (this | 343 | Toggle the displaying of server processes awaiting requests (this | |
344 | is the equivalent of the | 344 | is the equivalent of the | |
345 | .Fl a | 345 | .Fl a | |
346 | flag to | 346 | flag to | |
347 | .Ar netstat 1 ) . | 347 | .Ar netstat 1 ) . | |
348 | .It Cm numbers | 348 | .It Cm numbers | |
349 | Display network addresses numerically. | 349 | Display network addresses numerically. | |
350 | .It Cm names | 350 | .It Cm names | |
351 | Display network addresses symbolically. | 351 | Display network addresses symbolically. | |
352 | .It Ar protocol | 352 | .It Ar protocol | |
353 | Display only network connections using the indicated protocol | 353 | Display 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 | |
356 | Do not display information about connections associated with | 356 | Do not display information about connections associated with | |
357 | the specified hosts or ports. | 357 | the specified hosts or ports. | |
358 | Hosts and ports may be specified by name (``vangogh'', ``ftp''), | 358 | Hosts and ports may be specified by name (``vangogh'', ``ftp''), | |
359 | or numerically. | 359 | or numerically. | |
360 | Host addresses use the Internet dot notation (``128.32.0.9''). | 360 | Host addresses use the Internet dot notation (``128.32.0.9''). | |
361 | Multiple items may be specified with a single command by separating | 361 | Multiple items may be specified with a single command by separating | |
362 | them with spaces. | 362 | them with spaces. | |
363 | .It Cm display Op Ar items | 363 | .It Cm display Op Ar items | |
364 | Display information about the connections associated with the | 364 | Display information about the connections associated with the | |
365 | specified hosts or ports. | 365 | specified hosts or ports. | |
366 | As for | 366 | As for | |
367 | .Ar ignore , | 367 | .Ar ignore , | |
368 | .Op Ar items | 368 | .Op Ar items | |
369 | may be names or numbers. | 369 | may be names or numbers. | |
370 | .It Cm show Op Ar ports\&|hosts | 370 | .It Cm show Op Ar ports\&|hosts | |
371 | Show, on the command line, the currently selected protocols, | 371 | Show, on the command line, the currently selected protocols, | |
372 | hosts, and ports. | 372 | hosts, and ports. | |
373 | Hosts and ports which are being ignored are prefixed with a `!'. | 373 | Hosts and ports which are being ignored are prefixed with a `!'. | |
374 | If | 374 | If | |
375 | .Ar ports | 375 | .Ar ports | |
376 | or | 376 | or | |
377 | .Ar hosts | 377 | .Ar hosts | |
378 | is supplied as an argument to | 378 | is supplied as an argument to | |
379 | .Cm show , | 379 | .Cm show , | |
380 | then only the requested information will be displayed. | 380 | then only the requested information will be displayed. | |
381 | .It Cm reset | 381 | .It Cm reset | |
382 | Reset the port, host, and protocol matching mechanisms to the default | 382 | Reset 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 | |
386 | Display, in the lower window, those processes which are getting the | 386 | Display, in the lower window, those processes which are getting the | |
387 | largest portion of the processor (the default display). | 387 | largest portion of the processor (the default display). | |
388 | When less than 100% of the | 388 | When less than 100% of the | |
389 | processor is scheduled to user processes, the remaining time | 389 | processor is scheduled to user processes, the remaining time | |
390 | is accounted to the ``idle'' process. | 390 | is accounted to the ``idle'' process. | |
391 | .It Ic ps | 391 | .It Ic ps | |
392 | Display, in the lower window, the same information provided | 392 | Display, in the lower window, the same information provided | |
393 | by the command | 393 | by the command | |
394 | .Xr ps 1 | 394 | .Xr ps 1 | |
395 | with the flags | 395 | with the flags | |
396 | .Fl aux . | 396 | .Fl aux . | |
397 | .Pp | 397 | .Pp | |
398 | The following command is specific to the | 398 | The following command is specific to the | |
399 | .Ic ps | 399 | .Ic ps | |
400 | display; the minimum unambiguous prefix may be supplied. | 400 | display; 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 | |
404 | Limit the list of processes displayed to those owned by user | 404 | Limit the list of processes displayed to those owned by user | |
405 | .Ar name . | 405 | .Ar name . | |
406 | If | 406 | If | |
407 | .Ar name | 407 | .Ar name | |
408 | is specified as `+', processes owned by any user are displayed (default). | 408 | is specified as `+', processes owned by any user are displayed (default). | |
409 | .El | 409 | .El | |
410 | .It Ic swap | 410 | .It Ic swap | |
411 | Show information about swap space usage on all the | 411 | Show information about swap space usage on all the | |
412 | swap areas configured with | 412 | swap areas configured with | |
413 | .Xr swapctl 8 . | 413 | .Xr swapctl 8 . | |
414 | The first column is the device name of the partition. | 414 | The first column is the device name of the partition. | |
415 | The next column is the total space available in the partition. | 415 | The next column is the total space available in the partition. | |
416 | The | 416 | The | |
417 | .Ar Used | 417 | .Ar Used | |
418 | column indicates the total blocks used so far; | 418 | column indicates the total blocks used so far; | |
419 | the graph shows the percentage of space in use on each partition. | 419 | the graph shows the percentage of space in use on each partition. | |
420 | If there are more than one swap partition in use, | 420 | If there are more than one swap partition in use, | |
421 | a total line is also shown. | 421 | a total line is also shown. | |
422 | Areas known to the kernel, but not in use are shown as not available. | 422 | Areas known to the kernel, but not in use are shown as not available. | |
423 | .It Ic syscall | 423 | .It Ic syscall | |
424 | Show per system call statistics. | 424 | Show per system call statistics. | |
425 | The display consists of several columns of system call name and counts. | 425 | The display consists of several columns of system call name and counts. | |
426 | .Pp | 426 | .Pp | |
427 | In order to stop entries moving around the screen too much, an infinite | 427 | In order to stop entries moving around the screen too much, an infinite | |
428 | response filter is applied to the values before they are sorted. | 428 | response filter is applied to the values before they are sorted. | |
429 | .Pp | 429 | .Pp | |
430 | The following commands are specific to the | 430 | The following commands are specific to the | |
431 | .Ic syscall | 431 | .Ic syscall | |
432 | display: | 432 | display: | |
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 | |
436 | Sort display by the syscall name (default). | 436 | Sort display by the syscall name (default). | |
437 | .It Ic sort Ic count | 437 | .It Ic sort Ic count | |
438 | Sort display by the count of calls or time spent in the calls. | 438 | Sort display by the count of calls or time spent in the calls. | |
439 | .It Ic sort Ic syscall | 439 | .It Ic sort Ic syscall | |
440 | Sort display be syscall number. | 440 | Sort display be syscall number. | |
441 | .It Ic show Ic count | 441 | .It Ic show Ic count | |
442 | Show the number of times the system call has be called (default). | 442 | Show the number of times the system call has be called (default). | |
443 | .It Ic show Ic time | 443 | .It Ic show Ic time | |
444 | Show the average amount of time (in arbitrary units) spent in a call of | 444 | Show the average amount of time (in arbitrary units) spent in a call of | |
445 | the syscall. | 445 | the syscall. | |
446 | .El | 446 | .El | |
447 | .It Ic vmstat | 447 | .It Ic vmstat | |
448 | Take over the entire display and show a (rather crowded) compendium | 448 | Take over the entire display and show a (rather crowded) compendium | |
449 | of statistics related to virtual memory usage, process scheduling, | 449 | of statistics related to virtual memory usage, process scheduling, | |
450 | device interrupts, system name translation caching, disk | 450 | device interrupts, system name translation caching, disk | |
451 | .Tn I/O | 451 | .Tn I/O | |
452 | etc. | 452 | etc. | |
453 | .Pp | 453 | .Pp | |
454 | The upper left quadrant of the screen shows the number | 454 | The upper left quadrant of the screen shows the number | |
455 | of users logged in and the load average over the last one, five, | 455 | of users logged in and the load average over the last one, five, | |
456 | and fifteen minute intervals. | 456 | and fifteen minute intervals. | |
457 | Below this is a list of the | 457 | Below this are statistics on memory utilization. | |
458 | The first row of the table reports memory usage only among | |||
459 | active processes, that is processes that have run in the previous | |||
460 | twenty seconds. | |||
461 | The second row reports on memory usage of all processes. | |||
462 | The first column reports on the number of physical pages | |||
463 | claimed by processes. | |||
464 | The second column reports the number of physical pages that | |||
465 | are devoted to read only text pages. | |||
466 | The third and fourth columns report the same two figures for | |||
467 | virtual pages, that is the number of pages that would be | |||
468 | needed if all processes had all of their pages. | |||
469 | Finally the last column shows the number of physical pages | |||
470 | on the free list. | |||
471 | .Pp | |||
472 | Below the memory display is a list of the | |||
458 | average number of processes (over the last refresh interval) | 473 | average number of processes (over the last refresh interval) | |
459 | that are runnable (`r'), in page wait (`p'), | 474 | that are runnable (`r'), in page wait (`p'), | |
460 | in disk wait other than paging (`d'), sleeping (`s'). | 475 | in disk wait other than paging (`d'), sleeping (`s'). | |
461 | Below the queue length listing is a numerical listing and | 476 | Below the queue length listing is a numerical listing and | |
462 | a bar graph showing the amount of | 477 | a bar graph showing the amount of | |
463 | system (shown as `='), user (shown as `>'), | 478 | system (shown as `='), user (shown as `>'), | |
464 | nice (shown as `-'), and idle time (shown as ` '). | 479 | nice (shown as `-'), and idle time (shown as ` '). | |
465 | .Pp | 480 | .Pp | |
466 | To the right of the process statistics is a column that | 481 | To the right of the process statistics is a column that | |
467 | lists the average number of context switches (`Csw'), | 482 | lists the average number of context switches (`Csw'), | |
468 | traps (`Trp'; includes page faults), system calls (`Sys'), interrupts (`Int'), | 483 | traps (`Traps'; includes page faults), system calls (`SysCa'), interrupts (`Intr'), | |
469 | network software interrupts (`Sof'), | 484 | network software interrupts (`Soft'), | |
470 | page faults (`Flt'). | 485 | page faults (`Fault'). | |
471 | .Pp | 486 | .Pp | |
472 | Below this are statistics on memory utilization. | 487 | Below this are statistics on memory utilization. | |
473 | The first row of the table reports memory usage only among | 488 | The first row of the table reports memory usage only among | |
474 | active processes, that is processes that have run in the previous | 489 | active processes, that is processes that have run in the previous | |
475 | twenty seconds. | 490 | twenty seconds. | |
476 | The second row reports on memory usage of all processes. | 491 | The second row reports on memory usage of all processes. | |
477 | The first column reports on the number of physical pages | 492 | The first column reports on the number of physical pages | |
478 | claimed by processes. | 493 | claimed by processes. | |
479 | The second column reports the number of pages of memory and swap. | 494 | The second column reports the number of pages of memory and swap. | |
480 | The third column gives the number of pages of free memory and swap. | 495 | The third column gives the number of pages of free memory and swap. | |
481 | .Pp | 496 | .Pp | |
482 | Below the memory display are statistics on name translations. | 497 | Below the memory display are statistics on name translations. | |
483 | It lists the number of names translated in the previous interval, | 498 | It lists the number of names translated in the previous interval, | |
484 | the number and percentage of the translations that were | 499 | the number and percentage of the translations that were | |
485 | handled by the system wide name translation cache, and | 500 | handled by the system wide name translation cache, and | |
486 | the number and percentage of the translations that were | 501 | the number and percentage of the translations that were | |
487 | handled by the per process name translation cache. | 502 | handled by the per process name translation cache. | |
488 | .Pp | 503 | .Pp | |
489 | At the bottom left is the disk usage display. | 504 | At the bottom left is the disk usage display. | |
490 | It reports the number of seeks, transfers, number | 505 | It reports the number of seeks, transfers, number | |
491 | of kilobyte blocks transferred per second averaged over the | 506 | of kilobyte blocks transferred per second averaged over the | |
492 | refresh period of the display (by default, five seconds), and | 507 | refresh period of the display (by default, five seconds), and | |
493 | the time spent in disk accesses. | 508 | the time spent in disk accesses. | |
494 | If there are more than five disks, and the terminal window has more | 509 | If there are more than five disks, and the terminal window has more | |
495 | than 24 lines, the disks display will be flipped so that more | 510 | than 24 lines, the disks display will be flipped so that more | |
496 | of the disk statistics are visible. | 511 | of the disk statistics are visible. | |
497 | .Pp | 512 | .Pp | |
498 | Under the date in the upper right hand quadrant are statistics | 513 | Under the date in the upper right hand quadrant are statistics | |
499 | on paging and swapping activity. | 514 | on paging and swapping activity. | |
500 | The first two columns report the average number of pages | 515 | The first two columns report the average number of pages | |
501 | brought in and out per second over the last refresh interval | 516 | brought in and out per second over the last refresh interval | |
502 | due to page faults and the paging daemon. | 517 | due to page faults and the paging daemon. | |
503 | The third and fourth columns report the average number of pages | 518 | The third and fourth columns report the average number of pages | |
504 | brought in and out per second over the last refresh interval | 519 | brought in and out per second over the last refresh interval | |
505 | due to swap requests initiated by the scheduler. | 520 | due to swap requests initiated by the scheduler. | |
506 | The first row of the display shows the average | 521 | The first row of the display shows the average | |
507 | number of disk transfers per second over the last refresh interval; | 522 | number of disk transfers per second over the last refresh interval; | |
508 | the second row of the display shows the average | 523 | the second row of the display shows the average | |
509 | number of pages transferred per second over the last refresh interval. | 524 | number of pages transferred per second over the last refresh interval. | |
510 | .Pp | 525 | .Pp | |
511 | Below the paging statistics is another columns of paging data. | 526 | Below the paging statistics is another columns of paging data. | |
512 | From top to bottom, these represent average numbers of copy on write faults | 527 | From top to bottom, these represent: | |
513 | (`cow'), object cache lookups (`objlk'), object cache hits (`objht'), | 528 | .Pp | |
514 | pages zero filled on demand (`zfodw'), number zfod's created (`nzfod'), | 529 | .Bl -tag -width Fl -compact | |
515 | percentage of zfod's used (`%zfod'), number of kernel pages (`kern'), | 530 | .It Ic Sq forks | |
516 | number of wired pages (`wire'), number of active pages (`act'), number | 531 | number of fork() calls | |
517 | of inactive pages (`inact'), number of free pages (`free'), pages freed | 532 | .It Ic Sq fkppw | |
518 | by daemon (`daefr'), pages freed by exiting processes (`prcfr'), number | 533 | number of fork() calls where parent waits | |
519 | of 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 | 535 | number of fork() calls where vmspace is shared | |
521 | faults (`intrn'), per second over the refresh period. | 536 | .It Ic Sq pwait | |
537 | number of times fault had to wait on a page | |||
538 | .It Ic Sq relck | |||
539 | number of times uvmfault_relock() is called | |||
540 | .It Ic Sq rlkok | |||
541 | number of times uvmfault_relock() is a success | |||
542 | .It Ic Sq noram | |||
543 | number of times fault was out of RAM | |||
544 | .It Ic Sq ndcpy | |||
545 | number of times fault clears ``needs copy'' | |||
546 | .It Ic Sq fltcp | |||
547 | number of times fault promotes with copy (2b) | |||
548 | .It Ic Sq zfod | |||
549 | number of times fault promotes with zerofill (2b) | |||
550 | .It Ic Sq cow | |||
551 | number of times faulted for anonymous for Copy-On-Write (case 1b) | |||
552 | .It Ic Sq fmin | |||
553 | min number of free pages | |||
554 | .It Ic Sq ftarg | |||
555 | target number of free pages | |||
556 | .It Ic Sq itarg | |||
557 | target 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 | |||
571 | number 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 | |||
591 | number of pages daemon freed since boot | |||
592 | .It Ic Sq pdscn | |||
593 | number of pages daemon scaned since boot | |||
594 | .El | |||
595 | .Pp | |||
522 | Note that the `%zfod' percentage is usually less than 100%, | 596 | Note that the `%zfod' percentage is usually less than 100%, | |
523 | however it may exceed 100% if a large number of requests | 597 | however it may exceed 100% if a large number of requests | |
524 | are actually used long after they were set up during a | 598 | are actually used long after they were set up during a | |
525 | period when no new pages are being set up. | 599 | period when no new pages are being set up. | |
526 | Thus this figure is most interesting when observed over | 600 | Thus this figure is most interesting when observed over | |
527 | a long time period, such as from boot time | 601 | a 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 | |
530 | To the left of the column of paging statistics is a breakdown | 604 | To the left of the column of paging statistics is a breakdown | |
531 | of the interrupts being handled by the system. | 605 | of the interrupts being handled by the system. | |
532 | At the top of the list is the total interrupts per second | 606 | At the top of the list is the total interrupts per second | |
533 | over the time interval. | 607 | over the time interval. | |
534 | The rest of the column breaks down the total on a device | 608 | The rest of the column breaks down the total on a device | |
535 | by device basis. | 609 | by device basis. | |
536 | Only devices that have interrupted at least once since boot time are shown. | 610 | Only devices that have interrupted at least once since boot time are shown. | |
537 | .El | 611 | .El | |
538 | .Pp | 612 | .Pp | |
539 | Commands to switch between displays may be abbreviated to the | 613 | Commands to switch between displays may be abbreviated to the | |
540 | minimum unambiguous prefix; for example, ``io'' for ``iostat''. | 614 | minimum unambiguous prefix; for example, ``io'' for ``iostat''. | |
541 | Certain information may be discarded when the screen size is | 615 | Certain information may be discarded when the screen size is | |
542 | insufficient for display. | 616 | insufficient for display. | |
543 | For example, on a machine with 10 drives the | 617 | For example, on a machine with 10 drives the | |
544 | .Ic iostat | 618 | .Ic iostat | |
545 | bar graph displays only 3 drives on a 24 line terminal. | 619 | bar graph displays only 3 drives on a 24 line terminal. | |
546 | When a bar graph would overflow the allotted screen space it is | 620 | When a bar graph would overflow the allotted screen space it is | |
547 | truncated and the actual value is printed ``over top'' of the bar. | 621 | truncated and the actual value is printed ``over top'' of the bar. | |
548 | .Pp | 622 | .Pp | |
549 | The following commands are common to each display which shows | 623 | The following commands are common to each display which shows | |
550 | information about disk drives. | 624 | information about disk drives. | |
551 | These commands are used to select a set of drives to report on, | 625 | These commands are used to select a set of drives to report on, | |
552 | should your system have more drives configured than can normally | 626 | should your system have more drives configured than can normally | |
553 | be displayed on the screen. | 627 | be displayed on the screen. | |
554 | Drives may be specified as drive names or as patterns specified in the | 628 | Drives may be specified as drive names or as patterns specified in the | |
555 | notation described by | 629 | notation 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 | |
560 | Display information about the drives indicated. | 634 | Display information about the drives indicated. | |
561 | Multiple drives may be specified, separated by spaces. | 635 | Multiple drives may be specified, separated by spaces. | |
562 | .It Cm ignore Op Ar drives | 636 | .It Cm ignore Op Ar drives | |
563 | Do not display information about the drives indicated. | 637 | Do not display information about the drives indicated. | |
564 | Multiple drives may be specified, separated by spaces. | 638 | Multiple drives may be specified, separated by spaces. | |
565 | .It Cm drives Op Ar drives | 639 | .It Cm drives Op Ar drives | |
566 | With no arguments, display a list of available drives. | 640 | With no arguments, display a list of available drives. | |
567 | With arguments, replace the list of currently displayed drives | 641 | With arguments, replace the list of currently displayed drives | |
568 | with the ones specified. | 642 | with the ones specified. | |
569 | .El | 643 | .El | |
570 | .Pp | 644 | .Pp | |
571 | The following commands are specific to the | 645 | The following commands are specific to the | |
572 | .Ic inet.* , | 646 | .Ic inet.* , | |
573 | .Ic inet6.* , | 647 | .Ic inet6.* , | |
574 | .Ic syscall | 648 | .Ic syscall | |
575 | and | 649 | and | |
576 | .Ic vmstat | 650 | .Ic vmstat | |
577 | displays; the minimum unambiguous prefix may be supplied. | 651 | displays; 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 | |
581 | Display cumulative statistics since the system was booted. | 655 | Display cumulative statistics since the system was booted. | |
582 | .It Cm run | 656 | .It Cm run | |
583 | Display statistics as a running total from the point this | 657 | Display statistics as a running total from the point this | |
584 | command is given. | 658 | command is given. | |
585 | .It Cm time | 659 | .It Cm time | |
586 | Display statistics averaged over the refresh interval (the default). | 660 | Display statistics averaged over the refresh interval (the default). | |
587 | .It Cm zero | 661 | .It Cm zero | |
588 | Reset running statistics to zero. | 662 | Reset 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 | |
593 | For the namelist. | 667 | For the namelist. | |
594 | .It Pa /dev/kmem | 668 | .It Pa /dev/kmem | |
595 | For information in main memory. | 669 | For information in main memory. | |
596 | .It Pa /etc/hosts | 670 | .It Pa /etc/hosts | |
597 | For host names. | 671 | For host names. | |
598 | .It Pa /etc/networks | 672 | .It Pa /etc/networks | |
599 | For network names. | 673 | For network names. | |
600 | .It Pa /etc/services | 674 | .It Pa /etc/services | |
601 | For port names. | 675 | For port names. | |
602 | .El | 676 | .El | |
603 | .Sh NOTES | 677 | .Sh NOTES | |
604 | Much of the information that | 678 | Much of the information that | |
605 | .Nm | 679 | .Nm | |
606 | .Ic vmstat | 680 | .Ic vmstat | |
607 | uses is obtained from | 681 | uses 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 | |
618 | The | 692 | The | |
619 | .Nm | 693 | .Nm | |
620 | program appeared in | 694 | program appeared in | |
621 | .Bx 4.3 . | 695 | .Bx 4.3 . | |
622 | .Sh BUGS | 696 | .Sh BUGS | |
623 | Consumes CPU resources and thus may skew statistics. | 697 | Consumes CPU resources and thus may skew statistics. | |
624 | .Pp | 698 | .Pp | |
625 | Certain displays presume a minimum of 80 characters per line. | 699 | Certain displays presume a minimum of 80 characters per line. | |
626 | .Pp | 700 | .Pp | |
627 | The | 701 | The | |
628 | .Ic vmstat | 702 | .Ic vmstat | |
629 | display looks out of place because it is (it was added in as | 703 | display looks out of place because it is (it was added in as | |
630 | a separate display from what used to be a different program). | 704 | a separate display from what used to be a different program). | |
631 | .Pp | 705 | .Pp | |
632 | The | 706 | The | |
633 | .Fl b | 707 | .Fl b | |
634 | option requires a real terminal and could be converted to | 708 | option requires a real terminal and could be converted to | |
635 | simply output to standard output. | 709 | simply output to standard output. |
--- 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 | |||
36 | struct mode { | 36 | struct 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 | |||
48 | struct command { | 48 | struct 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)) |
--- 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 | |
35 | static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94"; | 35 | static 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 | |||
63 | static struct Info { | 63 | static 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 | |||
72 | enum display_mode display_mode = TIME; | 72 | enum display_mode display_mode = TIME; | |
73 | 73 | |||
74 | static void allocinfo(struct Info *); | 74 | static void allocinfo(struct Info *); | |
75 | static void copyinfo(struct Info *, struct Info *); | 75 | static void copyinfo(struct Info *, struct Info *); | |
76 | static float cputime(int); | 76 | static float cputime(int); | |
77 | static void dinfo(int, int, int); | 77 | static void dinfo(int, int, int); | |
78 | static void getinfo(struct Info *); | 78 | static void getinfo(struct Info *); | |
79 | static int ucount(void); | 79 | static int ucount(void); | |
80 | 80 | |||
81 | static char buf[26]; | 81 | static char buf[26]; | |
82 | static u_int64_t temp; | 82 | static u_int64_t temp; | |
83 | double etime; | 83 | double etime; | |
84 | static float hertz; | 84 | static float hertz; | |
85 | static int nintr; | 85 | static int nintr; | |
86 | static long *intrloc; | 86 | static long *intrloc; | |
87 | static char **intrname; | 87 | static char **intrname; | |
88 | static int nextintsrow; | 88 | static int nextintsrow; | |
89 | static int disk_horiz = 1; | 89 | static int disk_horiz = 1; | |
90 | static u_int nbuf; | |||
90 | 91 | |||
91 | WINDOW * | 92 | WINDOW * | |
92 | openvmstat(void) | 93 | openvmstat(void) | |
93 | { | 94 | { | |
94 | return (stdscr); | 95 | return (stdscr); | |
95 | } | 96 | } | |
96 | 97 | |||
97 | void | 98 | void | |
98 | closevmstat(WINDOW *w) | 99 | closevmstat(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 | |||
108 | static struct nlist namelist[] = { | 109 | static 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 | |||
149 | typedef struct intr_evcnt intr_evcnt_t; | 150 | typedef struct intr_evcnt intr_evcnt_t; | |
150 | struct intr_evcnt { | 151 | struct 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; | |
156 | int nevcnt; | 157 | int nevcnt; | |
157 | 158 | |||
158 | static void | 159 | static void | |
159 | get_interrupt_events(void) | 160 | get_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 | |||
195 | int | 196 | int | |
196 | initvmstat(void) | 197 | initvmstat(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 | |||
255 | void | 256 | void | |
256 | fetchvmstat(void) | 257 | fetchvmstat(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 | |||
266 | static void | 267 | static void | |
267 | print_ie_title(int i) | 268 | print_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 | |||
313 | void | 314 | void | |
314 | labelvmstat_top(void) | 315 | labelvmstat_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 | |||
335 | void | 336 | void | |
336 | labelvmstat(void) | 337 | labelvmstat(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 | |||
417 | static char cpuchar[CPUSTATES] = { '=' , '>', '-', '%', ' ' }; | 420 | static char cpuchar[CPUSTATES] = { '=' , '>', '-', '%', ' ' }; | |
418 | static char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_INTR, CP_IDLE }; | 421 | static char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_INTR, CP_IDLE }; | |
419 | 422 | |||
420 | void | 423 | void | |
421 | show_vmstat_top(vmtotal_t *Total, uvmexp_sysctl_t *uvm, uvmexp_sysctl_t *uvm1) | 424 | show_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 | |||
470 | void | 478 | void | |
471 | showvmstat(void) | 479 | showvmstat(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 */ | |||
555 | again: | |||
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 | |||
643 | void | 714 | void | |
644 | vmstat_boot(char *args) | 715 | vmstat_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 | |||
650 | void | 721 | void | |
651 | vmstat_run(char *args) | 722 | vmstat_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 | |||
657 | void | 728 | void | |
658 | vmstat_time(char *args) | 729 | vmstat_time(char *args) | |
659 | { | 730 | { | |
660 | display_mode = TIME; | 731 | display_mode = TIME; | |
661 | } | 732 | } | |
662 | 733 | |||
663 | void | 734 | void | |
664 | vmstat_zero(char *args) | 735 | vmstat_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 */ | |
671 | static int | 742 | static int | |
672 | ucount(void) | 743 | ucount(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 | |||
690 | static float | 761 | static float | |
691 | cputime(int indx) | 762 | cputime(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 | |||
704 | void | 775 | void | |
705 | puthumanint(u_int64_t n, int l, int c, int w) | 776 | puthumanint(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 | |||
722 | void | 793 | void | |
723 | putint(int n, int l, int c, int w) | 794 | putint(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 | |||
744 | void | 815 | void | |
745 | putfloat(double f, int l, int c, int w, int d, int nz) | 816 | putfloat(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 | |||
763 | static void | 834 | static void | |
764 | getinfo(struct Info *stats) | 835 | getinfo(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 | |||
799 | static void | 870 | static void | |
800 | allocinfo(struct Info *stats) | 871 | allocinfo(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 | |||
814 | static void | 885 | static void | |
815 | copyinfo(struct Info *from, struct Info *to) | 886 | copyinfo(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 | |||
827 | static void | 898 | static void | |
828 | dinfo(int dn, int r, int c) | 899 | dinfo(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 | } |