[BACK]Return to iostat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Annotation of src/usr.bin/systat/iostat.c, Revision 1.21

1.21    ! millert     1: /*     $OpenBSD: iostat.c,v 1.20 2003/02/02 18:20:41 henning 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: #ifndef lint
                     34: #if 0
                     35: static char sccsid[] = "@(#)iostat.c   8.1 (Berkeley) 6/6/93";
                     36: #endif
1.21    ! millert    37: static char rcsid[] = "$OpenBSD: iostat.c,v 1.20 2003/02/02 18:20:41 henning Exp $";
1.12      heko       38: #endif /* not lint */
1.1       deraadt    39:
                     40: #include <sys/param.h>
                     41: #include <sys/dkstat.h>
                     42: #include <sys/buf.h>
1.3       deraadt    43: #include <sys/time.h>
1.1       deraadt    44:
                     45: #include <string.h>
                     46: #include <stdlib.h>
                     47: #include <paths.h>
                     48: #include "systat.h"
                     49: #include "extern.h"
                     50:
1.3       deraadt    51: #include "dkstats.h"
1.19      tdeval     52: extern struct _disk    cur, last;
1.1       deraadt    53:
                     54: static  int linesperregion;
                     55: static  double etime;
                     56: static  int numbers = 0;               /* default display bar graphs */
1.3       deraadt    57: static  int secs = 0;                  /* default seconds shown */
1.1       deraadt    58:
1.17      millert    59: static int barlabels(int);
                     60: static void histogram(double, int, double);
                     61: static int numlabels(int);
                     62: static int stats(int, int, int);
                     63: static void stat1(int, int);
1.1       deraadt    64:
                     65:
                     66: WINDOW *
1.18      deraadt    67: openiostat(void)
1.1       deraadt    68: {
                     69:        return (subwin(stdscr, LINES-1-5, 0, 5, 0));
                     70: }
                     71:
                     72: void
1.18      deraadt    73: closeiostat(WINDOW *w)
1.1       deraadt    74: {
                     75:        if (w == NULL)
                     76:                return;
                     77:        wclear(w);
                     78:        wrefresh(w);
                     79:        delwin(w);
                     80: }
                     81:
                     82: int
1.18      deraadt    83: initiostat(void)
1.1       deraadt    84: {
1.3       deraadt    85:        dkinit(1);
                     86:        dkreadstats();
1.9       kstailey   87:        return (1);
1.1       deraadt    88: }
                     89:
                     90: void
1.18      deraadt    91: fetchiostat(void)
1.1       deraadt    92: {
1.19      tdeval     93:        if (cur.dk_ndrive == 0)
1.1       deraadt    94:                return;
1.3       deraadt    95:        dkreadstats();
1.1       deraadt    96: }
                     97:
                     98: #define        INSET   10
                     99:
                    100: void
1.18      deraadt   101: labeliostat(void)
1.1       deraadt   102: {
                    103:        int row;
                    104:
                    105:        row = 0;
                    106:        wmove(wnd, row, 0); wclrtobot(wnd);
                    107:        mvwaddstr(wnd, row++, INSET,
                    108:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    109:        mvwaddstr(wnd, row++, 0, "cpu  user|");
                    110:        mvwaddstr(wnd, row++, 0, "     nice|");
                    111:        mvwaddstr(wnd, row++, 0, "   system|");
                    112:        mvwaddstr(wnd, row++, 0, "interrupt|");
                    113:        mvwaddstr(wnd, row++, 0, "     idle|");
                    114:        if (numbers)
                    115:                row = numlabels(row + 1);
                    116:        else
                    117:                row = barlabels(row + 1);
                    118: }
                    119:
                    120: static int
1.18      deraadt   121: numlabels(int row)
1.1       deraadt   122: {
                    123:        int i, col, regions, ndrives;
                    124:
1.19      tdeval    125:        if (cur.dk_ndrive == 0) {
1.7       kstailey  126:                mvwaddstr(wnd, row++, INSET, "No drives attached.");
                    127:                return (row);
                    128:        }
1.11      deraadt   129: #define COLWIDTH       17
1.4       mickey    130: #define DRIVESPERLINE  ((wnd->_maxx - INSET) / COLWIDTH)
1.19      tdeval    131:        for (ndrives = 0, i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   132:                if (cur.dk_select[i])
1.1       deraadt   133:                        ndrives++;
                    134:        regions = howmany(ndrives, DRIVESPERLINE);
                    135:        /*
                    136:         * Deduct -regions for blank line after each scrolling region.
                    137:         */
1.4       mickey    138:        linesperregion = (wnd->_maxy - row - regions) / regions;
1.1       deraadt   139:        /*
                    140:         * Minimum region contains space for two
                    141:         * label lines and one line of statistics.
                    142:         */
                    143:        if (linesperregion < 3)
                    144:                linesperregion = 3;
1.11      deraadt   145:        col = INSET;
1.19      tdeval    146:        for (i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   147:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.11      deraadt   148:                        if (col + COLWIDTH >= wnd->_maxx) {
                    149:                                col = INSET, row += linesperregion + 1;
1.4       mickey    150:                                if (row > wnd->_maxy - (linesperregion + 1))
1.1       deraadt   151:                                        break;
                    152:                        }
1.3       deraadt   153:                        mvwaddstr(wnd, row, col + 4, cur.dk_name[i]);
1.11      deraadt   154:                        mvwaddstr(wnd, row + 1, col, " KBps tps  sec");
1.1       deraadt   155:                        col += COLWIDTH;
                    156:                }
                    157:        if (col)
                    158:                row += linesperregion + 1;
                    159:        return (row);
                    160: }
                    161:
                    162: static int
1.18      deraadt   163: barlabels(int row)
1.1       deraadt   164: {
                    165:        int i;
                    166:
1.19      tdeval    167:        if (cur.dk_ndrive == 0) {
1.7       kstailey  168:                mvwaddstr(wnd, row++, INSET, "No drives attached.");
                    169:                return (row);
                    170:        }
1.1       deraadt   171:        mvwaddstr(wnd, row++, INSET,
1.3       deraadt   172:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    173:        linesperregion = 2 + secs;
1.1       deraadt   174:        for (i = 0; i < dk_ndrive; i++)
1.3       deraadt   175:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    176:                        if (row > wnd->_maxy - linesperregion)
1.1       deraadt   177:                                break;
1.6       maja      178:                        mvwprintw(wnd, row++, 0, "%4.4s  Kps|", cur.dk_name[i]);
1.1       deraadt   179:                        mvwaddstr(wnd, row++, 0, "      tps|");
1.3       deraadt   180:                        if (secs)
                    181:                                mvwaddstr(wnd, row++, 0, "     msec|");
1.1       deraadt   182:                }
                    183:        return (row);
                    184: }
                    185:
                    186:
                    187: void
1.18      deraadt   188: showiostat(void)
1.1       deraadt   189: {
1.13      mpech     190:        int i, row, col;
1.1       deraadt   191:
1.3       deraadt   192:        dkswap();
                    193:
1.1       deraadt   194:        etime = 0;
1.18      deraadt   195:        for (i = 0; i < CPUSTATES; i++) {
1.3       deraadt   196:                etime += cur.cp_time[i];
1.1       deraadt   197:        }
                    198:        if (etime == 0.0)
                    199:                etime = 1.0;
                    200:        etime /= (float) hz;
                    201:        row = 1;
                    202:
                    203:        /*
                    204:         * Interrupt CPU state not calculated yet.
1.16      deraadt   205:         */
1.1       deraadt   206:        for (i = 0; i < CPUSTATES; i++)
                    207:                stat1(row++, i);
1.7       kstailey  208:
1.19      tdeval    209:        if (last.dk_ndrive != cur.dk_ndrive)
                    210:                labeliostat();
                    211:
                    212:        if (cur.dk_ndrive == 0)
1.7       kstailey  213:                return;
                    214:
1.1       deraadt   215:        if (!numbers) {
                    216:                row += 2;
1.19      tdeval    217:                for (i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   218:                        if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    219:                                if (row > wnd->_maxy - linesperregion)
1.1       deraadt   220:                                        break;
                    221:                                row = stats(row, INSET, i);
                    222:                        }
                    223:                return;
                    224:        }
1.11      deraadt   225:        col = INSET;
1.1       deraadt   226:        wmove(wnd, row + linesperregion, 0);
                    227:        wdeleteln(wnd);
                    228:        wmove(wnd, row + 3, 0);
                    229:        winsertln(wnd);
1.19      tdeval    230:        for (i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   231:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    232:                        if (col + COLWIDTH >= wnd->_maxx) {
1.11      deraadt   233:                                col = INSET, row += linesperregion + 1;
1.4       mickey    234:                                if (row > wnd->_maxy - (linesperregion + 1))
1.1       deraadt   235:                                        break;
                    236:                                wmove(wnd, row + linesperregion, 0);
                    237:                                wdeleteln(wnd);
                    238:                                wmove(wnd, row + 3, 0);
                    239:                                winsertln(wnd);
                    240:                        }
                    241:                        (void) stats(row + 3, col, i);
                    242:                        col += COLWIDTH;
                    243:                }
                    244: }
                    245:
                    246: static int
1.18      deraadt   247: stats(int row, int col, int dn)
1.1       deraadt   248: {
1.3       deraadt   249:        double atime, words;
                    250:
                    251:        /* time busy in disk activity */
                    252:        atime = (double)cur.dk_time[dn].tv_sec +
                    253:                ((double)cur.dk_time[dn].tv_usec / (double)1000000);
1.1       deraadt   254:
1.3       deraadt   255:        words = cur.dk_bytes[dn] / 1024.0;      /* # of K transferred */
1.1       deraadt   256:        if (numbers) {
1.11      deraadt   257:                mvwprintw(wnd, row, col, "%5.0f%4.0f%5.1f",
1.3       deraadt   258:                    words / etime, cur.dk_xfer[dn] / etime, atime / etime);
1.1       deraadt   259:                return (row);
                    260:        }
                    261:        wmove(wnd, row++, col);
1.3       deraadt   262:        histogram(words / etime, 50, 0.5);
1.1       deraadt   263:        wmove(wnd, row++, col);
1.3       deraadt   264:        histogram(cur.dk_xfer[dn] / etime, 50, 0.5);
                    265:        if (secs) {
1.1       deraadt   266:                wmove(wnd, row++, col);
1.3       deraadt   267:                atime *= 1000;  /* In milliseconds */
                    268:                histogram(atime / etime, 50, 0.5);
1.1       deraadt   269:        }
                    270:        return (row);
                    271: }
                    272:
                    273: static void
1.18      deraadt   274: stat1(int row, int o)
1.1       deraadt   275: {
1.13      mpech     276:        int i;
1.1       deraadt   277:        double time;
                    278:
                    279:        time = 0;
                    280:        for (i = 0; i < CPUSTATES; i++)
1.3       deraadt   281:                time += cur.cp_time[i];
1.1       deraadt   282:        if (time == 0.0)
                    283:                time = 1.0;
                    284:        wmove(wnd, row, INSET);
                    285: #define CPUSCALE       0.5
1.3       deraadt   286:        histogram(100.0 * cur.cp_time[o] / time, 50, CPUSCALE);
1.1       deraadt   287: }
                    288:
                    289: static void
1.18      deraadt   290: histogram(double val, int colwidth, double scale)
1.1       deraadt   291: {
1.20      henning   292:        int v = (int)(val * scale + 0.5);
                    293:        int factor = 1;
                    294:        int y, x;
                    295:
                    296:        while (v > colwidth) {
                    297:                v = (v + 5) / 10;
                    298:                factor *= 10;
1.1       deraadt   299:        }
1.20      henning   300:        getyx(wnd, y, x);
1.1       deraadt   301:        wclrtoeol(wnd);
1.20      henning   302:        whline(wnd, 'X', v);
                    303:        if (factor != 1)
                    304:                mvwprintw(wnd, y, x + colwidth + 1, "* %d ", factor);
1.1       deraadt   305: }
                    306:
                    307: int
1.18      deraadt   308: cmdiostat(char *cmd, char *args)
1.1       deraadt   309: {
                    310:
1.3       deraadt   311:        if (prefix(cmd, "secs"))
                    312:                secs = !secs;
1.1       deraadt   313:        else if (prefix(cmd, "numbers"))
                    314:                numbers = 1;
                    315:        else if (prefix(cmd, "bars"))
                    316:                numbers = 0;
                    317:        else if (!dkcmd(cmd, args))
                    318:                return (0);
                    319:        wclear(wnd);
                    320:        labeliostat();
                    321:        refresh();
                    322:        return (1);
                    323: }