Annotation of src/usr.bin/systat/iostat.c, Revision 1.32
1.32 ! thib 1: /* $OpenBSD: iostat.c,v 1.31 2008/06/13 08:18:47 canacar Exp $ */
1.3 deraadt 2: /* $NetBSD: iostat.c,v 1.5 1996/05/10 23:16:35 thorpej Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1980, 1992, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
1.21 millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: #include <sys/param.h>
34: #include <sys/dkstat.h>
35: #include <sys/buf.h>
1.3 deraadt 36: #include <sys/time.h>
1.29 beck 37: #include <sys/sysctl.h>
38: #include <sys/mount.h>
1.1 deraadt 39:
40: #include <string.h>
41: #include <stdlib.h>
42: #include <paths.h>
43: #include "systat.h"
44:
1.3 deraadt 45: #include "dkstats.h"
1.19 tdeval 46: extern struct _disk cur, last;
1.29 beck 47: struct bcachestats bclast, bccur;
1.1 deraadt 48:
1.25 dlg 49: static double etime;
1.1 deraadt 50:
1.30 canacar 51: void showtotal(void);
52: void showdrive(int);
53: void print_io(void);
54: int read_io(void);
55: int select_io(void);
56: void showbcache(void);
1.25 dlg 57:
1.26 dlg 58: #define ATIME(x,y) ((double)x[y].tv_sec + \
59: ((double)x[y].tv_usec / (double)1000000))
60:
1.1 deraadt 61:
1.30 canacar 62: field_def fields_io[] = {
63: {"DEVICE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
64: {"READ", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
65: {"WRITE", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
66: {"RTPS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
67: {"WTPS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
68: {"SEC", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.32 ! thib 69: {"", 8, 19, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.30 canacar 70: {"STATS", 12, 15, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}
71: };
72:
73: #define FIELD_ADDR(x) (&fields_io[x])
74:
75: #define FLD_IO_DEVICE FIELD_ADDR(0)
76: #define FLD_IO_READ FIELD_ADDR(1)
77: #define FLD_IO_WRITE FIELD_ADDR(2)
78: #define FLD_IO_RTPS FIELD_ADDR(3)
79: #define FLD_IO_WTPS FIELD_ADDR(4)
80: #define FLD_IO_SEC FIELD_ADDR(5)
81:
82: /* This is a hack that stuffs bcache statistics to the last two columns! */
83: #define FLD_IO_SVAL FIELD_ADDR(6)
84: #define FLD_IO_SSTR FIELD_ADDR(7)
85:
86: /* Define views */
87: field_def *view_io_0[] = {
88: FLD_IO_DEVICE, FLD_IO_READ, FLD_IO_WRITE, FLD_IO_RTPS,
89: FLD_IO_WTPS, FLD_IO_SEC, FLD_IO_SVAL, FLD_IO_SSTR, NULL
90: };
91:
92:
93: /* Define view managers */
94: struct view_manager iostat_mgr = {
95: "Iostat", select_io, read_io, NULL, print_header,
96: print_io, keyboard_callback, NULL, NULL
97: };
98:
99:
100: field_view views_io[] = {
101: {view_io_0, "iostat", '2', &iostat_mgr},
102: {NULL, NULL, 0, NULL}
103: };
1.1 deraadt 104:
105:
106: int
1.30 canacar 107: select_io(void)
1.1 deraadt 108: {
1.30 canacar 109: num_disp = cur.dk_ndrive + 1;
110: return (0);
1.1 deraadt 111: }
112:
1.30 canacar 113: int
114: read_io(void)
1.1 deraadt 115: {
1.29 beck 116: int mib[3];
117: size_t size;
118:
1.3 deraadt 119: dkreadstats();
1.30 canacar 120: dkswap();
121: num_disp = cur.dk_ndrive + 1;
1.29 beck 122:
123: bclast = bccur;
124: mib[0] = CTL_VFS;
125: mib[1] = VFS_GENERIC;
126: mib[2] = VFS_BCACHESTAT;
127: size = sizeof(bccur);
1.30 canacar 128:
1.29 beck 129: if (sysctl(mib, 3, &bccur, &size, NULL, 0) < 0)
1.30 canacar 130: error("cannot get vfs.bcachestat");
131:
1.29 beck 132: if (bclast.numbufs == 0)
133: bclast = bccur;
1.30 canacar 134:
135: return 0;
1.1 deraadt 136: }
137:
138:
139: void
1.30 canacar 140: print_io(void)
1.1 deraadt 141: {
1.30 canacar 142: int n, count = 0;
1.1 deraadt 143:
1.30 canacar 144: int i, curr;
1.31 canacar 145: etime = naptime;
1.19 tdeval 146:
1.30 canacar 147: /* XXX engine internals: save and restore curr_line for bcache */
148: curr = curr_line;
149:
150: for (n = dispstart; n < num_disp - 1; n++) {
151: showdrive(n);
152: count++;
153: if (maxprint > 0 && count >= maxprint)
154: break;
155: }
156:
157:
158: if (maxprint == 0 || count < maxprint)
159: showtotal();
160:
161: curr_line = curr;
162: showbcache();
163: }
164:
165: int
166: initiostat(void)
167: {
168: field_view *v;
169:
170: dkinit(1);
171: dkreadstats();
172:
173: bzero(&bccur, sizeof(bccur));
1.7 kstailey 174:
1.30 canacar 175: for (v = views_io; v->name != NULL; v++)
176: add_view(v);
1.29 beck 177:
1.30 canacar 178: return(1);
1.1 deraadt 179: }
180:
1.25 dlg 181: void
1.30 canacar 182: showtotal(void)
1.1 deraadt 183: {
1.25 dlg 184: double rsum, wsum, rtsum, wtsum, mssum;
1.30 canacar 185: int dn;
1.1 deraadt 186:
1.25 dlg 187: rsum = wsum = rtsum = wtsum = mssum = 0.0;
1.1 deraadt 188:
1.25 dlg 189: for (dn = 0; dn < cur.dk_ndrive; dn++) {
190: rsum += cur.dk_rbytes[dn] / etime;
1.26 dlg 191: wsum += cur.dk_wbytes[dn] / etime;
1.25 dlg 192: rtsum += cur.dk_rxfer[dn] / etime;
193: wtsum += cur.dk_wxfer[dn] / etime;
194: mssum += ATIME(cur.dk_time, dn) / etime;
1.1 deraadt 195: }
1.30 canacar 196:
197: print_fld_str(FLD_IO_DEVICE, "Totals");
198: print_fld_size(FLD_IO_READ, rsum);
199: print_fld_size(FLD_IO_WRITE, wsum);
200: print_fld_size(FLD_IO_RTPS, rtsum);
201: print_fld_size(FLD_IO_WTPS, wtsum);
202: print_fld_size(FLD_IO_SEC, mssum);
203:
204: end_line();
205: }
206:
207: void
208: showdrive(int dn)
209: {
210: print_fld_str(FLD_IO_DEVICE, cur.dk_name[dn]);
211: print_fld_size(FLD_IO_READ, cur.dk_rbytes[dn]/etime);
212: print_fld_size(FLD_IO_WRITE, cur.dk_wbytes[dn]/ etime);
213: print_fld_size(FLD_IO_RTPS, cur.dk_rxfer[dn] / etime);
214: print_fld_size(FLD_IO_WTPS, cur.dk_wxfer[dn] / etime);
215: print_fld_size(FLD_IO_SEC, ATIME(cur.dk_time, dn) / etime);
216:
217: end_line();
1.1 deraadt 218: }
219:
1.30 canacar 220:
221: #define ENDLINE do { \
222: count++; \
223: if (maxprint > 0 && count >= maxprint) \
224: return; \
225: } while(0)
226:
227: void
228: showbcache(void)
1.1 deraadt 229: {
1.30 canacar 230: int count = 0;
231:
232: print_fld_str(FLD_IO_SSTR, "numbufs");
233: print_fld_size(FLD_IO_SVAL, bccur.numbufs);
234: end_line();
235:
236: print_fld_str(FLD_IO_SSTR, "freebufs");
237: print_fld_size(FLD_IO_SVAL, bccur.freebufs);
238: end_line();
239:
240: print_fld_str(FLD_IO_SSTR, "numbufpages");
241: print_fld_size(FLD_IO_SVAL, bccur.numbufpages);
242: end_line();
243:
244: print_fld_str(FLD_IO_SSTR, "numfreepages");
245: print_fld_size(FLD_IO_SVAL, bccur.numfreepages);
246: end_line();
247:
248: print_fld_str(FLD_IO_SSTR, "numdirtypages");
249: print_fld_size(FLD_IO_SVAL, bccur.numdirtypages);
250: end_line();
251:
252: print_fld_str(FLD_IO_SSTR, "numcleanpages");
253: print_fld_size(FLD_IO_SVAL, bccur.numcleanpages);
254: end_line();
255:
256: print_fld_str(FLD_IO_SSTR, "pendingwrites");
257: print_fld_size(FLD_IO_SVAL, bccur.pendingwrites);
258: end_line();
259:
260: print_fld_str(FLD_IO_SSTR, "pendingreads");
261: print_fld_size(FLD_IO_SVAL, bccur.pendingreads);
262: end_line();
263:
264: print_fld_str(FLD_IO_SSTR, "numwrites");
265: print_fld_size(FLD_IO_SVAL, bccur.numwrites - bclast.numwrites);
266: end_line();
267:
268: print_fld_str(FLD_IO_SSTR, "numreads");
269: print_fld_size(FLD_IO_SVAL, bccur.numreads - bclast.numreads);
270: end_line();
271:
272: print_fld_str(FLD_IO_SSTR, "cachehits");
273: print_fld_size(FLD_IO_SVAL, bccur.cachehits - bclast.cachehits);
274: end_line();
1.1 deraadt 275: }