Annotation of src/usr.bin/systat/iostat.c, Revision 1.30
1.29 beck 1: /* $OpenBSD: iostat.c,v 1.28 2007/05/30 05:20:58 otto 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},
! 69: {"", 8, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
! 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.3 deraadt 145:
1.25 dlg 146: etime = 0.0;
1.30 ! canacar 147: for (i = 0; i < CPUSTATES; i++)
1.3 deraadt 148: etime += cur.cp_time[i];
1.25 dlg 149:
1.1 deraadt 150: if (etime == 0.0)
151: etime = 1.0;
1.25 dlg 152:
1.1 deraadt 153: etime /= (float) hz;
1.7 kstailey 154:
1.19 tdeval 155:
1.30 ! canacar 156: /* XXX engine internals: save and restore curr_line for bcache */
! 157: curr = curr_line;
! 158:
! 159: for (n = dispstart; n < num_disp - 1; n++) {
! 160: showdrive(n);
! 161: count++;
! 162: if (maxprint > 0 && count >= maxprint)
! 163: break;
! 164: }
! 165:
! 166:
! 167: if (maxprint == 0 || count < maxprint)
! 168: showtotal();
! 169:
! 170: curr_line = curr;
! 171: showbcache();
! 172: }
! 173:
! 174: int
! 175: initiostat(void)
! 176: {
! 177: field_view *v;
! 178:
! 179: dkinit(1);
! 180: dkreadstats();
! 181:
! 182: bzero(&bccur, sizeof(bccur));
1.7 kstailey 183:
1.30 ! canacar 184: for (v = views_io; v->name != NULL; v++)
! 185: add_view(v);
1.29 beck 186:
1.30 ! canacar 187: return(1);
1.1 deraadt 188: }
189:
1.25 dlg 190: void
1.30 ! canacar 191: showtotal(void)
1.1 deraadt 192: {
1.25 dlg 193: double rsum, wsum, rtsum, wtsum, mssum;
1.30 ! canacar 194: int dn;
1.1 deraadt 195:
1.25 dlg 196: rsum = wsum = rtsum = wtsum = mssum = 0.0;
1.1 deraadt 197:
1.25 dlg 198: for (dn = 0; dn < cur.dk_ndrive; dn++) {
199: rsum += cur.dk_rbytes[dn] / etime;
1.26 dlg 200: wsum += cur.dk_wbytes[dn] / etime;
1.25 dlg 201: rtsum += cur.dk_rxfer[dn] / etime;
202: wtsum += cur.dk_wxfer[dn] / etime;
203: mssum += ATIME(cur.dk_time, dn) / etime;
1.1 deraadt 204: }
1.30 ! canacar 205:
! 206: print_fld_str(FLD_IO_DEVICE, "Totals");
! 207: print_fld_size(FLD_IO_READ, rsum);
! 208: print_fld_size(FLD_IO_WRITE, wsum);
! 209: print_fld_size(FLD_IO_RTPS, rtsum);
! 210: print_fld_size(FLD_IO_WTPS, wtsum);
! 211: print_fld_size(FLD_IO_SEC, mssum);
! 212:
! 213: end_line();
! 214: }
! 215:
! 216: void
! 217: showdrive(int dn)
! 218: {
! 219: print_fld_str(FLD_IO_DEVICE, cur.dk_name[dn]);
! 220: print_fld_size(FLD_IO_READ, cur.dk_rbytes[dn]/etime);
! 221: print_fld_size(FLD_IO_WRITE, cur.dk_wbytes[dn]/ etime);
! 222: print_fld_size(FLD_IO_RTPS, cur.dk_rxfer[dn] / etime);
! 223: print_fld_size(FLD_IO_WTPS, cur.dk_wxfer[dn] / etime);
! 224: print_fld_size(FLD_IO_SEC, ATIME(cur.dk_time, dn) / etime);
! 225:
! 226: end_line();
1.1 deraadt 227: }
228:
1.30 ! canacar 229:
! 230: #define ENDLINE do { \
! 231: count++; \
! 232: if (maxprint > 0 && count >= maxprint) \
! 233: return; \
! 234: } while(0)
! 235:
! 236: void
! 237: showbcache(void)
1.1 deraadt 238: {
1.30 ! canacar 239: int count = 0;
! 240:
! 241: print_fld_str(FLD_IO_SSTR, "numbufs");
! 242: print_fld_size(FLD_IO_SVAL, bccur.numbufs);
! 243: end_line();
! 244:
! 245: print_fld_str(FLD_IO_SSTR, "freebufs");
! 246: print_fld_size(FLD_IO_SVAL, bccur.freebufs);
! 247: end_line();
! 248:
! 249: print_fld_str(FLD_IO_SSTR, "numbufpages");
! 250: print_fld_size(FLD_IO_SVAL, bccur.numbufpages);
! 251: end_line();
! 252:
! 253: print_fld_str(FLD_IO_SSTR, "numfreepages");
! 254: print_fld_size(FLD_IO_SVAL, bccur.numfreepages);
! 255: end_line();
! 256:
! 257: print_fld_str(FLD_IO_SSTR, "numdirtypages");
! 258: print_fld_size(FLD_IO_SVAL, bccur.numdirtypages);
! 259: end_line();
! 260:
! 261: print_fld_str(FLD_IO_SSTR, "numcleanpages");
! 262: print_fld_size(FLD_IO_SVAL, bccur.numcleanpages);
! 263: end_line();
! 264:
! 265: print_fld_str(FLD_IO_SSTR, "pendingwrites");
! 266: print_fld_size(FLD_IO_SVAL, bccur.pendingwrites);
! 267: end_line();
! 268:
! 269: print_fld_str(FLD_IO_SSTR, "pendingreads");
! 270: print_fld_size(FLD_IO_SVAL, bccur.pendingreads);
! 271: end_line();
! 272:
! 273: print_fld_str(FLD_IO_SSTR, "numwrites");
! 274: print_fld_size(FLD_IO_SVAL, bccur.numwrites - bclast.numwrites);
! 275: end_line();
! 276:
! 277: print_fld_str(FLD_IO_SSTR, "numreads");
! 278: print_fld_size(FLD_IO_SVAL, bccur.numreads - bclast.numreads);
! 279: end_line();
! 280:
! 281: print_fld_str(FLD_IO_SSTR, "cachehits");
! 282: print_fld_size(FLD_IO_SVAL, bccur.cachehits - bclast.cachehits);
! 283: end_line();
1.1 deraadt 284: }