Home | History | Annotate | Line # | Download | only in iostat
iostat.c revision 1.25.2.1
      1  1.25.2.1    lukem /*	$NetBSD: iostat.c,v 1.25.2.1 2002/06/30 05:48:05 lukem Exp $	*/
      2       1.9  thorpej 
      3       1.9  thorpej /*
      4       1.9  thorpej  * Copyright (c) 1996 John M. Vinopal
      5       1.9  thorpej  * All rights reserved.
      6       1.9  thorpej  *
      7       1.9  thorpej  * Redistribution and use in source and binary forms, with or without
      8       1.9  thorpej  * modification, are permitted provided that the following conditions
      9       1.9  thorpej  * are met:
     10       1.9  thorpej  * 1. Redistributions of source code must retain the above copyright
     11       1.9  thorpej  *    notice, this list of conditions and the following disclaimer.
     12       1.9  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.9  thorpej  *    notice, this list of conditions and the following disclaimer in the
     14       1.9  thorpej  *    documentation and/or other materials provided with the distribution.
     15       1.9  thorpej  * 3. All advertising materials mentioning features or use of this software
     16       1.9  thorpej  *    must display the following acknowledgement:
     17       1.9  thorpej  *      This product includes software developed for the NetBSD Project
     18       1.9  thorpej  *      by John M. Vinopal.
     19       1.9  thorpej  * 4. The name of the author may not be used to endorse or promote products
     20       1.9  thorpej  *    derived from this software without specific prior written permission.
     21       1.9  thorpej  *
     22       1.9  thorpej  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23       1.9  thorpej  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24       1.9  thorpej  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25       1.9  thorpej  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26       1.9  thorpej  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     27       1.9  thorpej  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     28       1.9  thorpej  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     29       1.9  thorpej  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     30       1.9  thorpej  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31       1.9  thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32       1.9  thorpej  * SUCH DAMAGE.
     33       1.9  thorpej  */
     34       1.8  thorpej 
     35       1.1      cgd /*-
     36       1.6      cgd  * Copyright (c) 1986, 1991, 1993
     37       1.9  thorpej  *      The Regents of the University of California.  All rights reserved.
     38       1.1      cgd  *
     39       1.1      cgd  * Redistribution and use in source and binary forms, with or without
     40       1.1      cgd  * modification, are permitted provided that the following conditions
     41       1.1      cgd  * are met:
     42       1.1      cgd  * 1. Redistributions of source code must retain the above copyright
     43       1.1      cgd  *    notice, this list of conditions and the following disclaimer.
     44       1.1      cgd  * 2. Redistributions in binary form must reproduce the above copyright
     45       1.1      cgd  *    notice, this list of conditions and the following disclaimer in the
     46       1.1      cgd  *    documentation and/or other materials provided with the distribution.
     47       1.1      cgd  * 3. All advertising materials mentioning features or use of this software
     48       1.1      cgd  *    must display the following acknowledgement:
     49       1.9  thorpej  *      This product includes software developed by the University of
     50       1.9  thorpej  *      California, Berkeley and its contributors.
     51       1.1      cgd  * 4. Neither the name of the University nor the names of its contributors
     52       1.1      cgd  *    may be used to endorse or promote products derived from this software
     53       1.1      cgd  *    without specific prior written permission.
     54       1.1      cgd  *
     55       1.1      cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     56       1.1      cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     57       1.1      cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     58       1.1      cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     59       1.1      cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     60       1.1      cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     61       1.1      cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     62       1.1      cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     63       1.1      cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     64       1.1      cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     65       1.1      cgd  * SUCH DAMAGE.
     66       1.1      cgd  */
     67       1.1      cgd 
     68      1.12    lukem #include <sys/cdefs.h>
     69       1.1      cgd #ifndef lint
     70      1.12    lukem __COPYRIGHT("@(#) Copyright (c) 1986, 1991, 1993\n\
     71      1.12    lukem         The Regents of the University of California.  All rights reserved.\n");
     72       1.1      cgd #endif /* not lint */
     73       1.1      cgd 
     74       1.1      cgd #ifndef lint
     75       1.8  thorpej #if 0
     76      1.11      mrg static char sccsid[] = "@(#)iostat.c	8.3 (Berkeley) 4/28/95";
     77       1.8  thorpej #else
     78  1.25.2.1    lukem __RCSID("$NetBSD: iostat.c,v 1.25.2.1 2002/06/30 05:48:05 lukem Exp $");
     79       1.8  thorpej #endif
     80       1.1      cgd #endif /* not lint */
     81       1.1      cgd 
     82      1.11      mrg #include <sys/types.h>
     83      1.22  thorpej #include <sys/sched.h>
     84       1.1      cgd #include <sys/dkstat.h>
     85       1.9  thorpej #include <sys/time.h>
     86       1.6      cgd 
     87       1.6      cgd #include <err.h>
     88       1.6      cgd #include <ctype.h>
     89       1.6      cgd #include <signal.h>
     90       1.1      cgd #include <stdio.h>
     91       1.1      cgd #include <stdlib.h>
     92       1.1      cgd #include <string.h>
     93       1.6      cgd #include <unistd.h>
     94       1.1      cgd 
     95       1.9  thorpej #include "dkstats.h"
     96       1.1      cgd 
     97       1.9  thorpej /* Namelist and memory files. */
     98       1.9  thorpej char	*nlistf, *memf;
     99       1.9  thorpej 
    100       1.9  thorpej int		hz, reps, interval;
    101       1.9  thorpej static int	todo = 0;
    102       1.9  thorpej 
    103       1.9  thorpej #define ISSET(x, a)	((x) & (a))
    104      1.15    lukem #define SHOW_CPU	1<<0
    105      1.15    lukem #define SHOW_TTY	1<<1
    106      1.15    lukem #define SHOW_STATS_1	1<<2
    107      1.15    lukem #define SHOW_STATS_2	1<<3
    108      1.15    lukem #define SHOW_STATS_X	1<<4
    109      1.15    lukem #define SHOW_TOTALS	1<<7
    110      1.15    lukem #define SHOW_STATS_ALL	(SHOW_STATS_1 | SHOW_STATS_2 | SHOW_STATS_X)
    111       1.9  thorpej 
    112      1.23   simonb static void cpustats(void);
    113      1.23   simonb static void disk_stats(double);
    114      1.23   simonb static void disk_stats2(double);
    115      1.23   simonb static void disk_statsx(double);
    116      1.23   simonb static void header(int);
    117      1.23   simonb static void usage(void);
    118      1.23   simonb static void display(void);
    119      1.23   simonb static void selectdrives(int, char **);
    120      1.23   simonb 
    121      1.23   simonb int main(int, char **);
    122       1.1      cgd 
    123       1.6      cgd int
    124      1.23   simonb main(int argc, char *argv[])
    125       1.1      cgd {
    126       1.9  thorpej 	int ch, hdrcnt;
    127       1.9  thorpej 	struct timeval	tv;
    128       1.9  thorpej 
    129      1.15    lukem 	while ((ch = getopt(argc, argv, "Cc:dDIM:N:Tw:x")) != -1)
    130       1.1      cgd 		switch(ch) {
    131       1.1      cgd 		case 'c':
    132       1.6      cgd 			if ((reps = atoi(optarg)) <= 0)
    133       1.6      cgd 				errx(1, "repetition count <= 0.");
    134       1.1      cgd 			break;
    135       1.9  thorpej 		case 'C':
    136       1.9  thorpej 			todo |= SHOW_CPU;
    137       1.9  thorpej 			break;
    138       1.9  thorpej 		case 'd':
    139      1.15    lukem 			todo &= ~SHOW_STATS_ALL;
    140       1.9  thorpej 			todo |= SHOW_STATS_1;
    141       1.9  thorpej 			break;
    142       1.9  thorpej 		case 'D':
    143      1.15    lukem 			todo &= ~SHOW_STATS_ALL;
    144       1.9  thorpej 			todo |= SHOW_STATS_2;
    145       1.9  thorpej 			break;
    146       1.9  thorpej 		case 'I':
    147       1.9  thorpej 			todo |= SHOW_TOTALS;
    148       1.9  thorpej 			break;
    149       1.1      cgd 		case 'M':
    150       1.6      cgd 			memf = optarg;
    151       1.1      cgd 			break;
    152       1.1      cgd 		case 'N':
    153       1.6      cgd 			nlistf = optarg;
    154       1.1      cgd 			break;
    155       1.9  thorpej 		case 'T':
    156       1.9  thorpej 			todo |= SHOW_TTY;
    157       1.9  thorpej 			break;
    158       1.1      cgd 		case 'w':
    159       1.6      cgd 			if ((interval = atoi(optarg)) <= 0)
    160       1.6      cgd 				errx(1, "interval <= 0.");
    161       1.1      cgd 			break;
    162      1.15    lukem 		case 'x':
    163      1.15    lukem 			todo &= ~SHOW_STATS_ALL;
    164      1.15    lukem 			todo |= SHOW_STATS_X;
    165      1.15    lukem 			break;
    166       1.1      cgd 		case '?':
    167       1.1      cgd 		default:
    168       1.1      cgd 			usage();
    169       1.1      cgd 		}
    170       1.1      cgd 	argc -= optind;
    171       1.1      cgd 	argv += optind;
    172       1.1      cgd 
    173      1.15    lukem 	if (!ISSET(todo, SHOW_CPU | SHOW_TTY | SHOW_STATS_ALL))
    174       1.9  thorpej 		todo |= SHOW_CPU | SHOW_TTY | SHOW_STATS_1;
    175      1.15    lukem 	if (ISSET(todo, SHOW_STATS_X)) {
    176      1.15    lukem 		todo &= ~(SHOW_CPU | SHOW_TTY | SHOW_STATS_ALL);
    177      1.15    lukem 		todo |= SHOW_STATS_X;
    178      1.15    lukem 	}
    179       1.9  thorpej 
    180       1.6      cgd 	/*
    181       1.6      cgd 	 * Discard setgid privileges if not the running kernel so that bad
    182       1.6      cgd 	 * guys can't print interesting stuff from kernel memory.
    183       1.6      cgd 	 */
    184       1.6      cgd 	if (nlistf != NULL || memf != NULL)
    185       1.6      cgd 		setgid(getgid());
    186       1.6      cgd 
    187      1.25   simonb 	dkinit(0);
    188       1.9  thorpej 	dkreadstats();
    189       1.9  thorpej 	selectdrives(argc, argv);
    190       1.1      cgd 
    191       1.9  thorpej 	tv.tv_sec = interval;
    192       1.9  thorpej 	tv.tv_usec = 0;
    193       1.1      cgd 
    194       1.9  thorpej 	/* print a new header on sigcont */
    195       1.9  thorpej 	(void)signal(SIGCONT, header);
    196       1.1      cgd 
    197       1.1      cgd 	for (hdrcnt = 1;;) {
    198       1.1      cgd 		if (!--hdrcnt) {
    199       1.9  thorpej 			header(0);
    200       1.1      cgd 			hdrcnt = 20;
    201       1.1      cgd 		}
    202       1.9  thorpej 
    203       1.9  thorpej 		if (!ISSET(todo, SHOW_TOTALS))
    204       1.9  thorpej 			dkswap();
    205       1.9  thorpej 		display();
    206       1.1      cgd 
    207       1.1      cgd 		if (reps >= 0 && --reps <= 0)
    208       1.1      cgd 			break;
    209       1.9  thorpej 		select(0, NULL, NULL, NULL, &tv);
    210       1.9  thorpej 		dkreadstats();
    211       1.1      cgd 	}
    212       1.1      cgd 	exit(0);
    213       1.1      cgd }
    214       1.1      cgd 
    215       1.9  thorpej static void
    216      1.23   simonb header(int signo)
    217       1.1      cgd {
    218      1.12    lukem 	int i;
    219       1.1      cgd 
    220      1.15    lukem 	if (ISSET(todo, SHOW_STATS_X))
    221      1.15    lukem 		return;
    222      1.15    lukem 
    223      1.15    lukem 					/* Main Headers. */
    224       1.9  thorpej 	if (ISSET(todo, SHOW_TTY))
    225       1.9  thorpej 		(void)printf("      tty");
    226       1.9  thorpej 
    227       1.9  thorpej 	if (ISSET(todo, SHOW_STATS_1))
    228      1.15    lukem 		for (i = 0; i < dk_ndrive; i++)
    229      1.15    lukem 			if (cur.dk_select[i])
    230      1.15    lukem 				(void)printf(
    231      1.18      mjl 				    "        %7.7s ", cur.dk_name[i]);
    232       1.9  thorpej 
    233       1.9  thorpej 	if (ISSET(todo, SHOW_STATS_2))
    234      1.15    lukem 		for (i = 0; i < dk_ndrive; i++)
    235      1.15    lukem 			if (cur.dk_select[i])
    236      1.15    lukem 				(void)printf(
    237      1.18      mjl 				    "       %7.7s ", cur.dk_name[i]);
    238       1.9  thorpej 
    239       1.9  thorpej 	if (ISSET(todo, SHOW_CPU))
    240       1.9  thorpej 		(void)printf("            cpu");
    241      1.15    lukem 
    242       1.9  thorpej 	printf("\n");
    243       1.9  thorpej 
    244      1.15    lukem 					/* Sub-Headers. */
    245       1.9  thorpej 	if (ISSET(todo, SHOW_TTY))
    246       1.9  thorpej 		printf(" tin tout");
    247       1.9  thorpej 
    248      1.15    lukem 	if (ISSET(todo, SHOW_STATS_1)) {
    249      1.15    lukem 		for (i = 0; i < dk_ndrive; i++)
    250      1.15    lukem 			if (cur.dk_select[i]) {
    251      1.15    lukem 				if (ISSET(todo, SHOW_TOTALS))
    252      1.15    lukem 					(void)printf("  KB/t xfr MB   ");
    253      1.15    lukem 				else
    254      1.15    lukem 					(void)printf("  KB/t t/s MB/s ");
    255      1.15    lukem 			}
    256      1.15    lukem 	}
    257       1.9  thorpej 
    258       1.9  thorpej 	if (ISSET(todo, SHOW_STATS_2))
    259      1.15    lukem 		for (i = 0; i < dk_ndrive; i++)
    260      1.15    lukem 			if (cur.dk_select[i])
    261      1.15    lukem 				(void)printf("   KB xfr time ");
    262       1.9  thorpej 
    263       1.9  thorpej 	if (ISSET(todo, SHOW_CPU))
    264       1.9  thorpej 		(void)printf(" us ni sy in id");
    265       1.9  thorpej 	printf("\n");
    266       1.1      cgd }
    267       1.1      cgd 
    268       1.9  thorpej static void
    269      1.23   simonb disk_stats(double etime)
    270       1.1      cgd {
    271      1.12    lukem 	int dn;
    272       1.9  thorpej 	double atime, mbps;
    273       1.1      cgd 
    274       1.1      cgd 	for (dn = 0; dn < dk_ndrive; ++dn) {
    275       1.9  thorpej 		if (!cur.dk_select[dn])
    276       1.1      cgd 			continue;
    277       1.9  thorpej 
    278      1.15    lukem 					/* average Kbytes per transfer. */
    279       1.9  thorpej 		if (cur.dk_xfer[dn])
    280       1.9  thorpej 			mbps = (cur.dk_bytes[dn] / (1024.0)) / cur.dk_xfer[dn];
    281       1.9  thorpej 		else
    282       1.9  thorpej 			mbps = 0.0;
    283  1.25.2.1    lukem 		(void)printf(" %5.2f", mbps);
    284       1.9  thorpej 
    285      1.15    lukem 					/* average transfers per second. */
    286       1.9  thorpej 		(void)printf(" %3.0f", cur.dk_xfer[dn] / etime);
    287       1.9  thorpej 
    288      1.15    lukem 					/* time busy in disk activity */
    289       1.9  thorpej 		atime = (double)cur.dk_time[dn].tv_sec +
    290       1.9  thorpej 			((double)cur.dk_time[dn].tv_usec / (double)1000000);
    291       1.9  thorpej 
    292      1.15    lukem 					/* Megabytes per second. */
    293       1.9  thorpej 		if (atime != 0.0)
    294       1.9  thorpej 			mbps = cur.dk_bytes[dn] / (double)(1024 * 1024);
    295  1.25.2.1    lukem 		else
    296       1.9  thorpej 			mbps = 0;
    297       1.9  thorpej 		(void)printf(" %4.2f ", mbps / etime);
    298       1.1      cgd 	}
    299       1.1      cgd }
    300       1.1      cgd 
    301       1.9  thorpej static void
    302      1.23   simonb disk_stats2(double etime)
    303       1.9  thorpej {
    304      1.12    lukem 	int dn;
    305       1.9  thorpej 	double atime;
    306       1.9  thorpej 
    307       1.9  thorpej 	for (dn = 0; dn < dk_ndrive; ++dn) {
    308       1.9  thorpej 		if (!cur.dk_select[dn])
    309       1.9  thorpej 			continue;
    310       1.9  thorpej 
    311      1.15    lukem 					/* average kbytes per second. */
    312       1.9  thorpej 		(void)printf(" %4.0f", cur.dk_bytes[dn] / (1024.0) / etime);
    313       1.9  thorpej 
    314      1.15    lukem 					/* average transfers per second. */
    315       1.9  thorpej 		(void)printf(" %3.0f", cur.dk_xfer[dn] / etime);
    316       1.9  thorpej 
    317      1.15    lukem 					/* average time busy in disk activity */
    318       1.9  thorpej 		atime = (double)cur.dk_time[dn].tv_sec +
    319       1.9  thorpej 			((double)cur.dk_time[dn].tv_usec / (double)1000000);
    320       1.9  thorpej 		(void)printf(" %4.2f ", atime / etime);
    321       1.9  thorpej 	}
    322       1.9  thorpej }
    323       1.9  thorpej 
    324       1.9  thorpej static void
    325      1.23   simonb disk_statsx(double etime)
    326      1.15    lukem {
    327      1.15    lukem 	int dn;
    328      1.15    lukem 	double atime, kbps;
    329      1.15    lukem 
    330      1.15    lukem 	if (ISSET(todo, SHOW_TOTALS))
    331      1.15    lukem 		(void)printf("device       KB/t      xfr     time       MB");
    332      1.15    lukem 	else
    333      1.15    lukem 		(void)printf("device       KB/t      t/s     time     MB/s");
    334      1.15    lukem 
    335      1.15    lukem 	for (dn = 0; dn < dk_ndrive; ++dn) {
    336      1.15    lukem 		(void)printf("\n");
    337      1.15    lukem 		(void)printf("%-8.8s", cur.dk_name[dn]);
    338      1.15    lukem 
    339      1.15    lukem 					/* average Kbytes per transfer */
    340      1.15    lukem 		if (cur.dk_xfer[dn])
    341      1.15    lukem 			kbps = (cur.dk_bytes[dn] / (1024.0)) / cur.dk_xfer[dn];
    342      1.15    lukem 		else
    343      1.15    lukem 			kbps = 0.0;
    344  1.25.2.1    lukem 		(void)printf(" %8.2f", kbps);
    345      1.15    lukem 
    346      1.15    lukem 					/* average transfers (per second) */
    347      1.15    lukem 		(void)printf(" %8.0f", cur.dk_xfer[dn] / etime);
    348      1.15    lukem 
    349      1.15    lukem 					/* time busy in disk activity */
    350      1.15    lukem 		atime = (double)cur.dk_time[dn].tv_sec +
    351      1.15    lukem 			((double)cur.dk_time[dn].tv_usec / (double)1000000);
    352      1.15    lukem 		(void)printf(" %8.2f", atime / etime);
    353      1.15    lukem 
    354      1.15    lukem 					/* average megabytes (per second) */
    355      1.17    lukem 		(void)printf(" %8.2f",
    356      1.15    lukem 		    cur.dk_bytes[dn] / (1024.0 * 1024) / etime);
    357      1.15    lukem 
    358      1.15    lukem 	}
    359      1.15    lukem }
    360      1.15    lukem 
    361      1.15    lukem static void
    362      1.23   simonb cpustats(void)
    363       1.1      cgd {
    364      1.12    lukem 	int state;
    365       1.1      cgd 	double time;
    366       1.1      cgd 
    367       1.1      cgd 	time = 0;
    368       1.1      cgd 	for (state = 0; state < CPUSTATES; ++state)
    369       1.1      cgd 		time += cur.cp_time[state];
    370       1.9  thorpej 	if (!time)
    371       1.9  thorpej 		time = 1.0;
    372      1.15    lukem 			/* States are generally never 100% and can use %3.0f. */
    373       1.1      cgd 	for (state = 0; state < CPUSTATES; ++state)
    374      1.21   simonb 		printf(" %2.0f", 100. * cur.cp_time[state] / time);
    375       1.1      cgd }
    376       1.1      cgd 
    377       1.9  thorpej static void
    378      1.23   simonb usage(void)
    379       1.1      cgd {
    380      1.13      mrg 
    381      1.16    enami 	(void)fprintf(stderr, "usage: iostat [-CdDITx] [-c count] [-M core] \
    382      1.16    enami [-N system] [-w wait] [drives]\n");
    383       1.1      cgd 	exit(1);
    384       1.9  thorpej }
    385       1.9  thorpej 
    386       1.9  thorpej static void
    387      1.23   simonb display(void)
    388       1.9  thorpej {
    389       1.9  thorpej 	double	etime;
    390       1.9  thorpej 
    391       1.9  thorpej 	/* Sum up the elapsed ticks. */
    392  1.25.2.1    lukem 	etime = cur.cp_etime;
    393       1.9  thorpej 
    394       1.9  thorpej 	/* If we're showing totals only, then don't divide by the
    395       1.9  thorpej 	 * system time.
    396       1.9  thorpej 	 */
    397       1.9  thorpej 	if (ISSET(todo, SHOW_TOTALS))
    398       1.9  thorpej 		etime = 1.0;
    399       1.9  thorpej 
    400       1.9  thorpej 	if (ISSET(todo, SHOW_TTY))
    401       1.9  thorpej 		printf("%4.0f %4.0f", cur.tk_nin / etime, cur.tk_nout / etime);
    402  1.25.2.1    lukem 
    403       1.9  thorpej 	if (ISSET(todo, SHOW_STATS_1))
    404       1.9  thorpej 		disk_stats(etime);
    405       1.9  thorpej 
    406       1.9  thorpej 	if (ISSET(todo, SHOW_STATS_2))
    407       1.9  thorpej 		disk_stats2(etime);
    408      1.15    lukem 
    409      1.15    lukem 	if (ISSET(todo, SHOW_STATS_X))
    410      1.15    lukem 		disk_statsx(etime);
    411       1.9  thorpej 
    412       1.9  thorpej 	if (ISSET(todo, SHOW_CPU))
    413       1.9  thorpej 		cpustats();
    414       1.9  thorpej 
    415       1.9  thorpej 	(void)printf("\n");
    416       1.9  thorpej 	(void)fflush(stdout);
    417       1.9  thorpej }
    418       1.9  thorpej 
    419       1.9  thorpej static void
    420      1.23   simonb selectdrives(int argc, char *argv[])
    421       1.9  thorpej {
    422       1.9  thorpej 	int	i, ndrives;
    423       1.9  thorpej 
    424       1.9  thorpej 	/*
    425       1.9  thorpej 	 * Choose drives to be displayed.  Priority goes to (in order) drives
    426       1.9  thorpej 	 * supplied as arguments and default drives.  If everything isn't
    427       1.9  thorpej 	 * filled in and there are drives not taken care of, display the first
    428       1.9  thorpej 	 * few that fit.
    429       1.9  thorpej 	 *
    430       1.9  thorpej 	 * The backward compatibility #ifdefs permit the syntax:
    431       1.9  thorpej 	 *	iostat [ drives ] [ interval [ count ] ]
    432       1.9  thorpej 	 */
    433      1.19     tron 	if (ISSET(todo, SHOW_STATS_X)) {
    434      1.19     tron 		for (i = 0; i < dk_ndrive; i++)
    435      1.19     tron 			cur.dk_select[i] = 1;
    436      1.19     tron 	}
    437      1.19     tron 
    438       1.9  thorpej #define	BACKWARD_COMPATIBILITY
    439       1.9  thorpej 	for (ndrives = 0; *argv; ++argv) {
    440       1.9  thorpej #ifdef	BACKWARD_COMPATIBILITY
    441       1.9  thorpej 		if (isdigit(**argv))
    442       1.9  thorpej 			break;
    443       1.9  thorpej #endif
    444      1.20     tron 		if (!ISSET(todo, SHOW_STATS_X))
    445      1.20     tron 			for (i = 0; i < dk_ndrive; i++) {
    446      1.20     tron 				if (strcmp(cur.dk_name[i], *argv))
    447      1.20     tron 					continue;
    448      1.20     tron 				cur.dk_select[i] = 1;
    449      1.20     tron 				++ndrives;
    450      1.20     tron 			}
    451       1.9  thorpej 	}
    452       1.9  thorpej #ifdef	BACKWARD_COMPATIBILITY
    453       1.9  thorpej 	if (*argv) {
    454       1.9  thorpej 		interval = atoi(*argv);
    455       1.9  thorpej 		if (*++argv)
    456       1.9  thorpej 			reps = atoi(*argv);
    457       1.9  thorpej 	}
    458       1.9  thorpej #endif
    459       1.9  thorpej 
    460       1.9  thorpej 	if (interval) {
    461       1.9  thorpej 		if (!reps)
    462       1.9  thorpej 			reps = -1;
    463       1.9  thorpej 	} else
    464       1.9  thorpej 		if (reps)
    465       1.9  thorpej 			interval = 1;
    466       1.9  thorpej 
    467       1.9  thorpej 	/* Pick up to 4 drives if none specified. */
    468       1.9  thorpej 	if (ndrives == 0)
    469       1.9  thorpej 		for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
    470       1.9  thorpej 			if (cur.dk_select[i])
    471       1.9  thorpej 				continue;
    472       1.9  thorpej 			cur.dk_select[i] = 1;
    473       1.9  thorpej 			++ndrives;
    474       1.9  thorpej 		}
    475       1.1      cgd }
    476