Annotation of src/usr.bin/systat/iostat.c, Revision 1.44
1.44 ! guenther 1: /* $OpenBSD: iostat.c,v 1.43 2014/09/15 19:08:21 miod 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>
1.43 miod 34: #include <sys/mount.h>
35: #include <sys/sched.h>
36: #include <sys/sysctl.h>
1.3 deraadt 37: #include <sys/time.h>
1.1 deraadt 38:
39: #include <string.h>
40: #include <stdlib.h>
41: #include <paths.h>
42: #include "systat.h"
43:
1.3 deraadt 44: #include "dkstats.h"
1.19 tdeval 45: extern struct _disk cur, last;
1.29 beck 46: struct bcachestats bclast, bccur;
1.1 deraadt 47:
1.25 dlg 48: static double etime;
1.1 deraadt 49:
1.30 canacar 50: void showtotal(void);
51: void showdrive(int);
52: void print_io(void);
53: int read_io(void);
54: int select_io(void);
55: void showbcache(void);
1.25 dlg 56:
1.26 dlg 57: #define ATIME(x,y) ((double)x[y].tv_sec + \
58: ((double)x[y].tv_usec / (double)1000000))
59:
1.1 deraadt 60:
1.30 canacar 61: field_def fields_io[] = {
62: {"DEVICE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
63: {"READ", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
64: {"WRITE", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
65: {"RTPS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
66: {"WTPS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
67: {"SEC", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.32 thib 68: {"", 8, 19, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.30 canacar 69: {"STATS", 12, 15, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}
70: };
71:
1.38 jasper 72: #define FLD_IO_DEVICE FIELD_ADDR(fields_io,0)
73: #define FLD_IO_READ FIELD_ADDR(fields_io,1)
74: #define FLD_IO_WRITE FIELD_ADDR(fields_io,2)
75: #define FLD_IO_RTPS FIELD_ADDR(fields_io,3)
76: #define FLD_IO_WTPS FIELD_ADDR(fields_io,4)
77: #define FLD_IO_SEC FIELD_ADDR(fields_io,5)
1.30 canacar 78:
79: /* This is a hack that stuffs bcache statistics to the last two columns! */
1.38 jasper 80: #define FLD_IO_SVAL FIELD_ADDR(fields_io,6)
81: #define FLD_IO_SSTR FIELD_ADDR(fields_io,7)
1.30 canacar 82:
83: /* Define views */
84: field_def *view_io_0[] = {
85: FLD_IO_DEVICE, FLD_IO_READ, FLD_IO_WRITE, FLD_IO_RTPS,
86: FLD_IO_WTPS, FLD_IO_SEC, FLD_IO_SVAL, FLD_IO_SSTR, NULL
87: };
88:
89:
90: /* Define view managers */
91: struct view_manager iostat_mgr = {
92: "Iostat", select_io, read_io, NULL, print_header,
93: print_io, keyboard_callback, NULL, NULL
94: };
95:
96:
97: field_view views_io[] = {
98: {view_io_0, "iostat", '2', &iostat_mgr},
99: {NULL, NULL, 0, NULL}
100: };
1.1 deraadt 101:
102:
103: int
1.30 canacar 104: select_io(void)
1.1 deraadt 105: {
1.30 canacar 106: num_disp = cur.dk_ndrive + 1;
107: return (0);
1.1 deraadt 108: }
109:
1.30 canacar 110: int
111: read_io(void)
1.1 deraadt 112: {
1.29 beck 113: int mib[3];
114: size_t size;
115:
1.3 deraadt 116: dkreadstats();
1.30 canacar 117: dkswap();
118: num_disp = cur.dk_ndrive + 1;
1.29 beck 119:
120: bclast = bccur;
121: mib[0] = CTL_VFS;
122: mib[1] = VFS_GENERIC;
123: mib[2] = VFS_BCACHESTAT;
124: size = sizeof(bccur);
1.30 canacar 125:
1.29 beck 126: if (sysctl(mib, 3, &bccur, &size, NULL, 0) < 0)
1.30 canacar 127: error("cannot get vfs.bcachestat");
128:
1.29 beck 129: if (bclast.numbufs == 0)
130: bclast = bccur;
1.30 canacar 131:
132: return 0;
1.1 deraadt 133: }
134:
135:
136: void
1.30 canacar 137: print_io(void)
1.1 deraadt 138: {
1.30 canacar 139: int n, count = 0;
1.1 deraadt 140:
1.35 canacar 141: int curr;
1.31 canacar 142: etime = naptime;
1.19 tdeval 143:
1.30 canacar 144: /* XXX engine internals: save and restore curr_line for bcache */
145: curr = curr_line;
146:
147: for (n = dispstart; n < num_disp - 1; n++) {
148: showdrive(n);
149: count++;
150: if (maxprint > 0 && count >= maxprint)
151: break;
152: }
153:
154:
155: if (maxprint == 0 || count < maxprint)
156: showtotal();
157:
158: curr_line = curr;
159: showbcache();
160: }
161:
162: int
163: initiostat(void)
164: {
165: field_view *v;
166:
167: dkinit(1);
168: dkreadstats();
169:
170: bzero(&bccur, sizeof(bccur));
1.7 kstailey 171:
1.30 canacar 172: for (v = views_io; v->name != NULL; v++)
173: add_view(v);
1.29 beck 174:
1.30 canacar 175: return(1);
1.1 deraadt 176: }
177:
1.25 dlg 178: void
1.30 canacar 179: showtotal(void)
1.1 deraadt 180: {
1.25 dlg 181: double rsum, wsum, rtsum, wtsum, mssum;
1.30 canacar 182: int dn;
1.1 deraadt 183:
1.25 dlg 184: rsum = wsum = rtsum = wtsum = mssum = 0.0;
1.1 deraadt 185:
1.25 dlg 186: for (dn = 0; dn < cur.dk_ndrive; dn++) {
187: rsum += cur.dk_rbytes[dn] / etime;
1.26 dlg 188: wsum += cur.dk_wbytes[dn] / etime;
1.25 dlg 189: rtsum += cur.dk_rxfer[dn] / etime;
190: wtsum += cur.dk_wxfer[dn] / etime;
191: mssum += ATIME(cur.dk_time, dn) / etime;
1.1 deraadt 192: }
1.30 canacar 193:
194: print_fld_str(FLD_IO_DEVICE, "Totals");
195: print_fld_size(FLD_IO_READ, rsum);
196: print_fld_size(FLD_IO_WRITE, wsum);
197: print_fld_size(FLD_IO_RTPS, rtsum);
198: print_fld_size(FLD_IO_WTPS, wtsum);
1.34 naddy 199: print_fld_float(FLD_IO_SEC, mssum, 1);
1.30 canacar 200:
201: end_line();
202: }
203:
204: void
205: showdrive(int dn)
206: {
207: print_fld_str(FLD_IO_DEVICE, cur.dk_name[dn]);
208: print_fld_size(FLD_IO_READ, cur.dk_rbytes[dn]/etime);
209: print_fld_size(FLD_IO_WRITE, cur.dk_wbytes[dn]/ etime);
210: print_fld_size(FLD_IO_RTPS, cur.dk_rxfer[dn] / etime);
211: print_fld_size(FLD_IO_WTPS, cur.dk_wxfer[dn] / etime);
1.34 naddy 212: print_fld_float(FLD_IO_SEC, ATIME(cur.dk_time, dn) / etime, 1);
1.30 canacar 213:
214: end_line();
1.1 deraadt 215: }
1.30 canacar 216:
217: void
218: showbcache(void)
1.1 deraadt 219: {
1.39 beck 220: print_fld_str(FLD_IO_SSTR, "total pages");
1.33 thib 221: print_fld_ssize(FLD_IO_SVAL, bccur.numbufpages);
1.41 beck 222: end_line();
223:
1.40 beck 224: print_fld_str(FLD_IO_SSTR, "dirty pages");
225: print_fld_ssize(FLD_IO_SVAL, bccur.numdirtypages);
226: end_line();
227:
228: print_fld_str(FLD_IO_SSTR, "delwri bufs");
229: print_fld_ssize(FLD_IO_SVAL, bccur.delwribufs);
230: end_line();
231:
232: print_fld_str(FLD_IO_SSTR, "busymap bufs");
233: print_fld_ssize(FLD_IO_SVAL, bccur.busymapped);
234: end_line();
235:
236: print_fld_str(FLD_IO_SSTR, "avail kvaslots");
237: print_fld_ssize(FLD_IO_SVAL, bccur.kvaslots_avail);
1.30 canacar 238: end_line();
239:
1.40 beck 240: print_fld_str(FLD_IO_SSTR, "kvaslots");
241: print_fld_ssize(FLD_IO_SVAL, bccur.kvaslots);
1.30 canacar 242: end_line();
243:
1.39 beck 244: print_fld_str(FLD_IO_SSTR, "pending writes");
1.33 thib 245: print_fld_ssize(FLD_IO_SVAL, bccur.pendingwrites);
1.30 canacar 246: end_line();
247:
1.39 beck 248: print_fld_str(FLD_IO_SSTR, "pending reads");
1.33 thib 249: print_fld_ssize(FLD_IO_SVAL, bccur.pendingreads);
1.30 canacar 250: end_line();
251:
1.39 beck 252: print_fld_str(FLD_IO_SSTR, "cache hits");
1.33 thib 253: print_fld_ssize(FLD_IO_SVAL, bccur.cachehits - bclast.cachehits);
1.30 canacar 254: end_line();
1.1 deraadt 255: }