From: tholo Date: Sun, 3 Mar 1996 02:52:32 +0000 (+0000) Subject: WOrking disk statistics; NetBSD PR 2161 X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=79e81f8e1285b8a5fb93209d29b36a6522193e86;p=openbsd WOrking disk statistics; NetBSD PR 2161 --- diff --git a/usr.sbin/iostat/Makefile b/usr.sbin/iostat/Makefile index 20ebf133c8f..0dcd91ce116 100644 --- a/usr.sbin/iostat/Makefile +++ b/usr.sbin/iostat/Makefile @@ -1,10 +1,16 @@ -# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $OpenBSD: Makefile,v 1.2 1996/03/03 02:52:32 tholo Exp $ +# $NetBSD: Makefile,v 1.12 1995/12/22 08:04:27 jonathan Exp $ +# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= iostat .if (${MACHINE_ARCH} == "m68k") -CFLAGS+=-D${MACHINE} -I${.CURDIR}/../../sys/arch +CFLAGS+=-D${MACHINE} .endif -CFLAGS+=-I${.CURDIR}/../../usr.bin/vmstat + +.PATH: ${.CURDIR}/../../usr.bin/vmstat + +CFLAGS+=-I${.CURDIR}/../../sys/arch -I${.CURDIR}/../../usr.bin/vmstat +SRCS= dkstats.c iostat.c MAN= iostat.8 DPADD= ${LIBKVM} LDADD= -lkvm diff --git a/usr.sbin/iostat/iostat.8 b/usr.sbin/iostat/iostat.8 index b2c56cc440f..16f27ba1eb0 100644 --- a/usr.sbin/iostat/iostat.8 +++ b/usr.sbin/iostat/iostat.8 @@ -1,3 +1,6 @@ +.\" $OpenBSD: iostat.8,v 1.2 1996/03/03 02:52:33 tholo Exp $ +.\" $NetBSD: iostat.8,v 1.8 1995/11/28 20:16:30 thorpej Exp $ +.\" .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -30,11 +33,10 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)iostat.8 8.1 (Berkeley) 6/6/93 -.\" $Id: iostat.8,v 1.1.1.1 1995/10/18 08:47:37 deraadt Exp $ .\" -.Dd June 6, 1993 +.Dd Jan 18, 1996 .Dt IOSTAT 8 -.Os BSD 4 +.Os NetBSD 1.1 .Sh NAME .Nm iostat .Nd report @@ -42,6 +44,7 @@ statistics .Sh SYNOPSIS .Nm iostat +.Op Fl CdDIT .Op Fl c Ar count .Op Fl M Ar core .Op Fl N Ar system @@ -51,8 +54,19 @@ statistics .Nm Iostat displays kernel .Tn I/O -statistics on terminal, disk and cpu -operations. +statistics on terminal, disk and cpu operations. By default, +.Nm iostat +displays one line of statistics averaged over the machine's run time. +The use of +.Fl c +presents successive lines averaged over the +.Ar wait +period. +The +.Fl I +option causes +.Nm iostat +to print raw, unaveraged values. .Pp The options are as follows: .Bl -tag -width flag @@ -60,18 +74,44 @@ The options are as follows: Repeat the display .Ar count times. -The first display is for the time since a reboot and each subsequent -report is for the time period since the last display. +Unless the +.Fl I +flag is in effect, the first display is for the time since a reboot and +each subsequent report is for the time period since the last display. If no .Ar wait interval is specified, the default is 1 second. +.It Fl C +Show cpu statistics. This is enabled by default unless the +.Fl d, +.Fl D, +or +.Fl T +flags are used. +.It Fl d +Show disk statistics. This is the default. Displays kilobytes per +transfer, number of transfers, and megabytes transfered. Use of this +flag disables display of cpu and tty statistics. +.It Fl D +Show alternate disk statistics. Displays kilobytes transfered, number of +transfers, and time spent in transfers. Use of this flag disables the +default display. +.It Fl I +Show the running total values, rather than an average. .It Fl M Extract values associated with the name list from the specified core instead of the default -.Dq Pa /dev/kmem . +.Dq Pa /dev/mem . .It Fl N Extract the name list from the specified system instead of the default .Dq Pa /netbsd . +.It Fl T +Show tty statistics. This is enabled by default unless the +.Fl C, +.Fl d, +or +.Fl D +flags are used. .It Fl w Pause .Ar wait @@ -92,7 +132,7 @@ characters read from terminals characters written to terminals .El .It disks -Disk operations (this field is system dependent). +Disk operations. The header of the field is the disk name and unit number. If more than four disk drives are configured in the system, .Nm iostat @@ -103,13 +143,24 @@ to display specific drives, their names may be supplied on the command line. .Pp .Bl -tag -width indent -compact -.It sps -sectors transferred per second -.It tps +.It K/t +Kilobytes transferred per disk transfer +.It t/s transfers per second -.It msps -milliseconds per average seek (including implied -seeks and rotational latency) +.It Mb/s +Megabytes transferred per second +.Pp +.El +The alternate display format, (selected with +.Fl D +), presents the following values. +.Bl -tag -width indent -compact +.It Kb +Kilobytes transferred +.It xfr +Disk transfers +.It time +Seconds spent in disk activity .El .It cpu .Bl -tag -width indent -compact @@ -124,10 +175,10 @@ seeks and rotational latency) .El .El .Sh FILES -.Bl -tag -width /dev/kmem -compact +.Bl -tag -width /dev/mem -compact .It Pa /netbsd Default kernel namelist. -.It Pa /dev/kmem +.It Pa /dev/mem Default memory file. .El .Sh SEE ALSO diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c index deaaaf600da..a9313ed3b47 100644 --- a/usr.sbin/iostat/iostat.c +++ b/usr.sbin/iostat/iostat.c @@ -1,6 +1,41 @@ +/* $OpenBSD: iostat.c,v 1.2 1996/03/03 02:52:34 tholo Exp $ */ +/* $NetBSD: iostat.c,v 1.8 1995/11/28 20:16:31 thorpej Exp $ */ + +/* + * Copyright (c) 1996 John M. Vinopal (banshee@resort.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by John M. Vinopal. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- * Copyright (c) 1986, 1991, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -12,8 +47,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -34,127 +69,95 @@ #ifndef lint static char copyright[] = "@(#) Copyright (c) 1986, 1991, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; + The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/* from: static char sccsid[] = "@(#)iostat.c 8.2 (Berkeley) 1/26/94"; */ -static char *rcsid = "$Id: iostat.c,v 1.1.1.1 1995/10/18 08:47:37 deraadt Exp $"; +#if 0 +static char sccsid[] = "@(#)iostat.c 8.2 (Berkeley) 1/26/94"; +#else +static char *rcsid = "$NetBSD: iostat.c,v 1.8 1995/11/28 20:16:31 thorpej Exp $" +; +#endif #endif /* not lint */ -#include -#include #include +#include #include #include -#include -#include -#include -#include -#include #include #include #include #include #include -struct nlist namelist[] = { -#define X_DK_TIME 0 - { "_dk_time" }, -#define X_DK_XFER 1 - { "_dk_xfer" }, -#define X_DK_WDS 2 - { "_dk_wds" }, -#define X_TK_NIN 3 - { "_tk_nin" }, -#define X_TK_NOUT 4 - { "_tk_nout" }, -#define X_DK_SEEK 5 - { "_dk_seek" }, -#define X_CP_TIME 6 - { "_cp_time" }, -#define X_DK_WPMS 7 - { "_dk_wpms" }, -#define X_HZ 8 - { "_hz" }, -#define X_STATHZ 9 - { "_stathz" }, -#define X_DK_NDRIVE 10 - { "_dk_ndrive" }, -#define X_END 10 -#if defined(hp300) || defined(luna68k) -#define X_HPDINIT (X_END+1) - { "_hp_dinit" }, -#endif -#ifdef mips -#define X_SCSI_DINIT (X_END+1) - { "_scsi_dinit" }, -#endif -#ifdef tahoe -#define X_VBDINIT (X_END+1) - { "_vbdinit" }, -#endif -#ifdef vax - { "_mbdinit" }, -#define X_MBDINIT (X_END+1) - { "_ubdinit" }, -#define X_UBDINIT (X_END+2) -#endif - { NULL }, -}; - -struct _disk { - long cp_time[CPUSTATES]; - long *dk_time; - long *dk_wds; - long *dk_seek; - long *dk_xfer; - long tk_nin; - long tk_nout; -} cur, last; - -kvm_t *kd; -double etime; -long *dk_wpms; -int dk_ndrive, *dr_select, hz, kmemfd, ndrives; -char **dr_name; - -#define nlread(x, v) \ - kvm_read(kd, namelist[x].n_value, &(v), sizeof(v)) - -#include "names.c" /* XXX */ - -void cpustats __P((void)); -void dkstats __P((void)); -void phdr __P((int)); -void usage __P((void)); +#include "dkstats.h" + +/* Defined in dkstats.c */ +extern struct _disk cur; +extern int dk_ndrive; + +char *nlistf = NULL; +char *memf = NULL; + +int hz, reps, interval; +static int todo = 0; + +#define ISSET(x, a) ((x) & (a)) +#define SHOW_CPU 0x0001 +#define SHOW_TTY 0x0002 +#define SHOW_STATS_1 0x0004 +#define SHOW_STATS_2 0x0008 +#define SHOW_TOTALS 0x0080 + +static void cpustats __P((void)); +static void disk_stats __P((double)); +static void disk_stats2 __P((double)); +static void header __P((int)); +static void usage __P((void)); +static void display __P((void)); +static void selectdrives __P((int, char **)); + +void dkswap __P((void)); +void dkreadstats __P((void)); +int dkinit __P((int)); int main(argc, argv) int argc; char *argv[]; { - register int i; - long tmp; - int ch, hdrcnt, reps, interval, stathz, ndrives; - char **cp, *memf, *nlistf, buf[30]; - char errbuf[_POSIX2_LINE_MAX]; - - interval = reps = 0; - nlistf = memf = NULL; - while ((ch = getopt(argc, argv, "c:M:N:w:")) != EOF) + int ch, hdrcnt; + struct timeval tv; + + while ((ch = getopt(argc, argv, "Cc:dDIM:N:Tw:")) != EOF) switch(ch) { case 'c': if ((reps = atoi(optarg)) <= 0) errx(1, "repetition count <= 0."); break; + case 'C': + todo |= SHOW_CPU; + break; + case 'd': + todo |= SHOW_STATS_1; + break; + case 'D': + todo |= SHOW_STATS_2; + break; + case 'I': + todo |= SHOW_TOTALS; + break; case 'M': memf = optarg; break; case 'N': nlistf = optarg; break; + case 'T': + todo |= SHOW_TTY; + break; case 'w': if ((interval = atoi(optarg)) <= 0) errx(1, "interval <= 0."); @@ -166,6 +169,9 @@ main(argc, argv) argc -= optind; argv += optind; + if (!ISSET(todo, SHOW_CPU | SHOW_TTY | SHOW_STATS_1 | SHOW_STATS_2)) + todo |= SHOW_CPU | SHOW_TTY | SHOW_STATS_1; + /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. @@ -173,203 +179,139 @@ main(argc, argv) if (nlistf != NULL || memf != NULL) setgid(getgid()); - kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); - if (kd == 0) - errx(1, "kvm_openfiles: %s", errbuf); - if (kvm_nlist(kd, namelist) == -1) - errx(1, "kvm_nlist: %s", kvm_geterr(kd)); - if (namelist[X_DK_NDRIVE].n_type == 0) - errx(1, "dk_ndrive not found in namelist"); - (void)nlread(X_DK_NDRIVE, dk_ndrive); - if (dk_ndrive <= 0) - errx(1, "invalid dk_ndrive %d\n", dk_ndrive); - - cur.dk_time = calloc(dk_ndrive, sizeof(long)); - cur.dk_wds = calloc(dk_ndrive, sizeof(long)); - cur.dk_seek = calloc(dk_ndrive, sizeof(long)); - cur.dk_xfer = calloc(dk_ndrive, sizeof(long)); - last.dk_time = calloc(dk_ndrive, sizeof(long)); - last.dk_wds = calloc(dk_ndrive, sizeof(long)); - last.dk_seek = calloc(dk_ndrive, sizeof(long)); - last.dk_xfer = calloc(dk_ndrive, sizeof(long)); - dr_select = calloc(dk_ndrive, sizeof(int)); - dr_name = calloc(dk_ndrive, sizeof(char *)); - dk_wpms = calloc(dk_ndrive, sizeof(long)); - - for (i = 0; i < dk_ndrive; i++) { - (void)sprintf(buf, "dk%d", i); - dr_name[i] = strdup(buf); - } - if (!read_names()) - exit(1); - (void)nlread(X_HZ, hz); - (void)nlread(X_STATHZ, stathz); - if (stathz) - hz = stathz; - (void)kvm_read(kd, namelist[X_DK_WPMS].n_value, dk_wpms, - dk_ndrive * sizeof(dk_wpms)); - - /* - * Choose drives to be displayed. Priority goes to (in order) drives - * supplied as arguments and default drives. If everything isn't - * filled in and there are drives not taken care of, display the first - * few that fit. - * - * The backward compatibility #ifdefs permit the syntax: - * iostat [ drives ] [ interval [ count ] ] - */ -#define BACKWARD_COMPATIBILITY - for (ndrives = 0; *argv; ++argv) { -#ifdef BACKWARD_COMPATIBILITY - if (isdigit(**argv)) - break; -#endif - for (i = 0; i < dk_ndrive; i++) { - if (strcmp(dr_name[i], *argv)) - continue; - dr_select[i] = 1; - ++ndrives; - } - } -#ifdef BACKWARD_COMPATIBILITY - if (*argv) { - interval = atoi(*argv); - if (*++argv) - reps = atoi(*argv); - } -#endif - - if (interval) { - if (!reps) - reps = -1; - } else - if (reps) - interval = 1; + dkinit(0); + dkreadstats(); + selectdrives(argc, argv); - for (i = 0; i < dk_ndrive && ndrives < 4; i++) { - if (dr_select[i] || dk_wpms[i] == 0) - continue; - for (cp = defdrives; *cp; cp++) - if (strcmp(dr_name[i], *cp) == 0) { - dr_select[i] = 1; - ++ndrives; - break; - } - } - for (i = 0; i < dk_ndrive && ndrives < 4; i++) { - if (dr_select[i]) - continue; - dr_select[i] = 1; - ++ndrives; - } + tv.tv_sec = interval; + tv.tv_usec = 0; - (void)signal(SIGCONT, phdr); + /* print a new header on sigcont */ + (void)signal(SIGCONT, header); for (hdrcnt = 1;;) { if (!--hdrcnt) { - phdr(0); + header(0); hdrcnt = 20; } - (void)kvm_read(kd, namelist[X_DK_TIME].n_value, - cur.dk_time, dk_ndrive * sizeof(long)); - (void)kvm_read(kd, namelist[X_DK_XFER].n_value, - cur.dk_xfer, dk_ndrive * sizeof(long)); - (void)kvm_read(kd, namelist[X_DK_WDS].n_value, - cur.dk_wds, dk_ndrive * sizeof(long)); - (void)kvm_read(kd, namelist[X_DK_SEEK].n_value, - cur.dk_seek, dk_ndrive * sizeof(long)); - (void)kvm_read(kd, namelist[X_TK_NIN].n_value, - &cur.tk_nin, sizeof(cur.tk_nin)); - (void)kvm_read(kd, namelist[X_TK_NOUT].n_value, - &cur.tk_nout, sizeof(cur.tk_nout)); - (void)kvm_read(kd, namelist[X_CP_TIME].n_value, - cur.cp_time, sizeof(cur.cp_time)); - for (i = 0; i < dk_ndrive; i++) { - if (!dr_select[i]) - continue; -#define X(fld) tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp - X(dk_xfer); - X(dk_seek); - X(dk_wds); - X(dk_time); - } - tmp = cur.tk_nin; - cur.tk_nin -= last.tk_nin; - last.tk_nin = tmp; - tmp = cur.tk_nout; - cur.tk_nout -= last.tk_nout; - last.tk_nout = tmp; - etime = 0; - for (i = 0; i < CPUSTATES; i++) { - X(cp_time); - etime += cur.cp_time[i]; - } - if (etime == 0.0) - etime = 1.0; - etime /= (float)hz; - (void)printf("%4.0f%5.0f", - cur.tk_nin / etime, cur.tk_nout / etime); - dkstats(); - cpustats(); - (void)printf("\n"); - (void)fflush(stdout); + + if (!ISSET(todo, SHOW_TOTALS)) + dkswap(); + display(); if (reps >= 0 && --reps <= 0) break; - (void)sleep(interval); + select(0, NULL, NULL, NULL, &tv); + dkreadstats(); } exit(0); } -/* ARGUSED */ -void -phdr(signo) +static void +header(signo) int signo; { register int i; - (void)printf(" tty"); + /* Main Headers. */ + if (ISSET(todo, SHOW_TTY)) + (void)printf(" tty"); + + if (ISSET(todo, SHOW_STATS_1)) + for (i = 0; i < dk_ndrive; i++) + if (cur.dk_select[i]) + (void)printf(" %3.3s ", cur.dk_name[i]); + + if (ISSET(todo, SHOW_STATS_2)) for (i = 0; i < dk_ndrive; i++) - if (dr_select[i]) - (void)printf(" %3.3s ", dr_name[i]); - (void)printf(" cpu\n tin tout"); + if (cur.dk_select[i]) + (void)printf(" %3.3s ", cur.dk_name[i]); + + if (ISSET(todo, SHOW_CPU)) + (void)printf(" cpu"); + printf("\n"); + + /* Sub-Headers. */ + if (ISSET(todo, SHOW_TTY)) + printf(" tin tout"); + + if (ISSET(todo, SHOW_STATS_1)) + for (i = 0; i < dk_ndrive; i++) + if (cur.dk_select[i]) + if (ISSET(todo, SHOW_TOTALS)) + (void)printf(" K/t xfr Mb "); + else + (void)printf(" K/t t/s Mb/s "); + + if (ISSET(todo, SHOW_STATS_2)) for (i = 0; i < dk_ndrive; i++) - if (dr_select[i]) - (void)printf(" sps tps msps "); - (void)printf(" us ni sy in id\n"); + if (cur.dk_select[i]) + (void)printf(" Kb xfr time "); + + if (ISSET(todo, SHOW_CPU)) + (void)printf(" us ni sy in id"); + printf("\n"); +} + +static void +disk_stats(etime) +double etime; +{ + register int dn; + double atime, mbps; + + for (dn = 0; dn < dk_ndrive; ++dn) { + if (!cur.dk_select[dn]) + continue; + + /* average Kbytes per transfer. */ + if (cur.dk_xfer[dn]) + mbps = (cur.dk_bytes[dn] / (1024.0)) / cur.dk_xfer[dn]; + else + mbps = 0.0; + (void)printf(" %5.2f", mbps); + + /* average transfers per second. */ + (void)printf(" %3.0f", cur.dk_xfer[dn] / etime); + + /* time busy in disk activity */ + atime = (double)cur.dk_time[dn].tv_sec + + ((double)cur.dk_time[dn].tv_usec / (double)1000000); + + /* Megabytes per second. */ + if (atime != 0.0) + mbps = cur.dk_bytes[dn] / (double)(1024 * 1024); + else + mbps = 0; + (void)printf(" %4.2f ", mbps / etime); + } } -void -dkstats() +static void +disk_stats2(etime) +double etime; { register int dn; - double atime, itime, msps, words, xtime; + double atime; for (dn = 0; dn < dk_ndrive; ++dn) { - if (!dr_select[dn]) + if (!cur.dk_select[dn]) continue; - words = cur.dk_wds[dn] * 32; /* words xfer'd */ - (void)printf("%4.0f", /* sectors */ - words / (DEV_BSIZE / 2) / etime); - - (void)printf("%4.0f", cur.dk_xfer[dn] / etime); - - if (dk_wpms[dn] && cur.dk_xfer[dn]) { - atime = cur.dk_time[dn]; /* ticks disk busy */ - atime /= (float)hz; /* ticks to seconds */ - xtime = words / dk_wpms[dn]; /* transfer time */ - itime = atime - xtime; /* time not xfer'ing */ - if (itime < 0) - msps = 0; - else - msps = itime * 1000 / cur.dk_xfer[dn]; - } else - msps = 0; - (void)printf("%5.1f ", msps); + + /* average kbytes per second. */ + (void)printf(" %4.0f", cur.dk_bytes[dn] / (1024.0) / etime); + + /* average transfers per second. */ + (void)printf(" %3.0f", cur.dk_xfer[dn] / etime); + + /* average time busy in disk activity. */ + atime = (double)cur.dk_time[dn].tv_sec + + ((double)cur.dk_time[dn].tv_usec / (double)1000000); + (void)printf(" %4.2f ", atime / etime); } } -void +static void cpustats() { register int state; @@ -378,15 +320,109 @@ cpustats() time = 0; for (state = 0; state < CPUSTATES; ++state) time += cur.cp_time[state]; + if (!time) + time = 1.0; + /* States are generally never 100% and can use %3.0f. */ for (state = 0; state < CPUSTATES; ++state) - (void)printf("%3.0f", - 100. * cur.cp_time[state] / (time ? time : 1)); + printf("%3.0f", 100. * cur.cp_time[state] / time); } -void +static void usage() { (void)fprintf(stderr, -"usage: iostat [-c count] [-M core] [-N system] [-w wait] [drives]\n"); +"usage: iostat [-CdDIT] [-c count] [-M core] [-N system] [-w wait] [drives]\n"); exit(1); } + +static void +display() +{ + int i; + double etime; + + /* Sum up the elapsed ticks. */ + etime = 0.0; + for (i = 0; i < CPUSTATES; i++) { + etime += cur.cp_time[i]; + } + if (etime == 0.0) + etime = 1.0; + /* Convert to seconds. */ + etime /= (float)hz; + + /* If we're showing totals only, then don't divide by the + * system time. + */ + if (ISSET(todo, SHOW_TOTALS)) + etime = 1.0; + + if (ISSET(todo, SHOW_TTY)) + printf("%4.0f %4.0f", cur.tk_nin / etime, cur.tk_nout / etime); + + if (ISSET(todo, SHOW_STATS_1)) + disk_stats(etime); + + if (ISSET(todo, SHOW_STATS_2)) + disk_stats2(etime); + + if (ISSET(todo, SHOW_CPU)) + cpustats(); + + (void)printf("\n"); + (void)fflush(stdout); +} + +static void +selectdrives(argc, argv) +int argc; +char *argv[]; +{ + int i, ndrives; + + /* + * Choose drives to be displayed. Priority goes to (in order) drives + * supplied as arguments and default drives. If everything isn't + * filled in and there are drives not taken care of, display the first + * few that fit. + * + * The backward compatibility #ifdefs permit the syntax: + * iostat [ drives ] [ interval [ count ] ] + */ +#define BACKWARD_COMPATIBILITY + for (ndrives = 0; *argv; ++argv) { +#ifdef BACKWARD_COMPATIBILITY + if (isdigit(**argv)) + break; +#endif + for (i = 0; i < dk_ndrive; i++) { + if (strcmp(cur.dk_name[i], *argv)) + continue; + cur.dk_select[i] = 1; + ++ndrives; + } + } +#ifdef BACKWARD_COMPATIBILITY + if (*argv) { + interval = atoi(*argv); + if (*++argv) + reps = atoi(*argv); + } +#endif + + if (interval) { + if (!reps) + reps = -1; + } else + if (reps) + interval = 1; + + /* Pick up to 4 drives if none specified. */ + if (ndrives == 0) + for (i = 0; i < dk_ndrive && ndrives < 4; i++) { + if (cur.dk_select[i]) + continue; + cur.dk_select[i] = 1; + ++ndrives; + } +}