iostat.c revision 1.29
1/* $OpenBSD: iostat.c,v 1.29 2008/06/12 17:53:49 beck Exp $ */ 2/* $NetBSD: iostat.c,v 1.5 1996/05/10 23:16:35 thorpej Exp $ */ 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. 16 * 3. Neither the name of the University nor the names of its contributors 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#ifndef lint 34#if 0 35static char sccsid[] = "@(#)iostat.c 8.1 (Berkeley) 6/6/93"; 36#endif 37static char rcsid[] = "$OpenBSD: iostat.c,v 1.29 2008/06/12 17:53:49 beck Exp $"; 38#endif /* not lint */ 39 40#include <sys/param.h> 41#include <sys/dkstat.h> 42#include <sys/buf.h> 43#include <sys/time.h> 44#include <sys/sysctl.h> 45#include <sys/mount.h> 46 47#include <string.h> 48#include <stdlib.h> 49#include <paths.h> 50#include "systat.h" 51#include "extern.h" 52 53#include "dkstats.h" 54extern struct _disk cur, last; 55struct bcachestats bclast, bccur; 56 57static double etime; 58 59static void numlabels(void); 60 61#define ATIME(x,y) ((double)x[y].tv_sec + \ 62 ((double)x[y].tv_usec / (double)1000000)) 63 64#define NFMT "%-6.6s %8.0f %8.0f %6.0f %6.0f %4.1f" 65#define SFMT "%-6.6s %8s %8s %6s %6s %4s" 66#define BCSCOL 50 67 68WINDOW * 69openiostat(void) 70{ 71 bzero(&bccur, sizeof(bccur)); 72 return (subwin(stdscr, LINES-1-1, 0, 1, 0)); 73} 74 75void 76closeiostat(WINDOW *w) 77{ 78 if (w == NULL) 79 return; 80 wclear(w); 81 wrefresh(w); 82 delwin(w); 83} 84 85int 86initiostat(void) 87{ 88 dkinit(1); 89 dkreadstats(); 90 return (1); 91} 92 93void 94fetchiostat(void) 95{ 96 int mib[3]; 97 size_t size; 98 99 if (cur.dk_ndrive == 0) 100 return; 101 dkreadstats(); 102 103 bclast = bccur; 104 mib[0] = CTL_VFS; 105 mib[1] = VFS_GENERIC; 106 mib[2] = VFS_BCACHESTAT; 107 size = sizeof(bccur); 108 if (sysctl(mib, 3, &bccur, &size, NULL, 0) < 0) 109 mvwaddstr(wnd, 20, 0, "cannot get vfs.bcachestat"); 110 if (bclast.numbufs == 0) 111 bclast = bccur; 112} 113 114void 115labeliostat(void) 116{ 117 mvwprintw(wnd, 1, 0, SFMT, "Device", "rKBytes", "wKBytes", "rtps", 118 "wtps", "sec"); 119 mvwprintw(wnd, 1, BCSCOL + 16, "numbufs"); 120 mvwprintw(wnd, 2, BCSCOL + 16, "freebufs"); 121 mvwprintw(wnd, 3, BCSCOL + 16, "numbufpages"); 122 mvwprintw(wnd, 4, BCSCOL + 16, "numfreepages"); 123 mvwprintw(wnd, 5, BCSCOL + 16, "numdirtypages"); 124 mvwprintw(wnd, 6, BCSCOL + 16, "numcleanpages"); 125 mvwprintw(wnd, 7, BCSCOL + 16, "pendingwrites"); 126 mvwprintw(wnd, 8, BCSCOL + 16, "pendingreads"); 127 mvwprintw(wnd, 9, BCSCOL + 16, "numwrites"); 128 mvwprintw(wnd, 10, BCSCOL + 16, "numreads"); 129 mvwprintw(wnd, 11, BCSCOL + 16, "cachehits"); 130} 131 132void 133showiostat(void) 134{ 135 int i; 136 137 dkswap(); 138 139 etime = 0.0; 140 for (i = 0; i < CPUSTATES; i++) { 141 etime += cur.cp_time[i]; 142 } 143 144 if (etime == 0.0) 145 etime = 1.0; 146 147 etime /= (float) hz; 148 149 if (last.dk_ndrive != cur.dk_ndrive) 150 labeliostat(); 151 152 if (cur.dk_ndrive == 0) 153 return; 154 155 numlabels(); 156 157 mvwprintw(wnd, 1, BCSCOL, "%15ld", bccur.numbufs); 158 mvwprintw(wnd, 2, BCSCOL, "%15ld", bccur.freebufs); 159 mvwprintw(wnd, 3, BCSCOL, "%15ld", bccur.numbufpages); 160 if (bccur.numfreepages) 161 mvwprintw(wnd, 4, BCSCOL, "%15ld", bccur.numfreepages); 162 else 163 mvwprintw(wnd, 4, BCSCOL, "%15s", ""); 164 if (bccur.numdirtypages) 165 mvwprintw(wnd, 5, BCSCOL, "%15ld", bccur.numdirtypages); 166 else 167 mvwprintw(wnd, 5, BCSCOL, "%15s", ""); 168 if (bccur.numcleanpages) 169 mvwprintw(wnd, 6, BCSCOL, "%15ld", bccur.numcleanpages); 170 else 171 mvwprintw(wnd, 6, BCSCOL, "%15s", ""); 172 if (bccur.pendingwrites) 173 mvwprintw(wnd, 7, BCSCOL, "%15ld", bccur.pendingwrites); 174 else 175 mvwprintw(wnd, 7, BCSCOL, "%15s", ""); 176 if (bccur.pendingreads) 177 mvwprintw(wnd, 8, BCSCOL, "%15ld", bccur.pendingreads); 178 else 179 mvwprintw(wnd, 8, BCSCOL, "%15s", ""); 180 if (bccur.numwrites - bclast.numwrites) 181 mvwprintw(wnd, 9, BCSCOL, "%15ld", 182 bccur.numwrites - bclast.numwrites); 183 else 184 mvwprintw(wnd, 9, BCSCOL, "%15s", ""); 185 if (bccur.numreads - bclast.numreads) 186 mvwprintw(wnd, 10, BCSCOL, "%15ld", 187 bccur.numreads - bclast.numreads); 188 else 189 mvwprintw(wnd, 10, BCSCOL, "%15s", ""); 190 if (bccur.cachehits - bclast.cachehits) 191 mvwprintw(wnd, 11, BCSCOL, "%15ld", 192 bccur.cachehits - bclast.cachehits); 193 else 194 mvwprintw(wnd, 11, BCSCOL, "%15s", ""); 195} 196 197void 198numlabels(void) 199{ 200 double rsum, wsum, rtsum, wtsum, mssum; 201 int row, dn; 202 203 row = 2; 204 wmove(wnd, 0, 0); 205 wclrtoeol(wnd); 206 207 if (cur.dk_ndrive == 0) { 208 mvwaddstr(wnd, row, 0, "No drives attached."); 209 return; 210 } 211 212 rsum = wsum = rtsum = wtsum = mssum = 0.0; 213 214 for (dn = 0; dn < cur.dk_ndrive; dn++) { 215 rsum += cur.dk_rbytes[dn] / etime; 216 wsum += cur.dk_wbytes[dn] / etime; 217 rtsum += cur.dk_rxfer[dn] / etime; 218 wtsum += cur.dk_wxfer[dn] / etime; 219 mssum += ATIME(cur.dk_time, dn) / etime; 220 mvwprintw(wnd, row++, 0, NFMT, 221 cur.dk_name[dn], 222 cur.dk_rbytes[dn] / 1024.0 / etime, 223 cur.dk_wbytes[dn] / 1024.0 / etime, 224 cur.dk_rxfer[dn] / etime, 225 cur.dk_wxfer[dn] / etime, 226 ATIME(cur.dk_time, dn) / etime); 227 } 228 mvwprintw(wnd, row++, 0, NFMT, 229 "Totals", rsum / 1024.0, wsum / 1024.0, rtsum, wtsum, mssum); 230} 231 232int 233cmdiostat(char *cmd, char *args) 234{ 235 wclear(wnd); 236 labeliostat(); 237 refresh(); 238 return (1); 239} 240