* Copyright (c) 1986, 1991 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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 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.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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
"@(#) Copyright (c) 1986, 1991 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)iostat.c 5.9 (Berkeley) 6/27/91";
#define X_HPDINIT (X_END+1)
#define X_VBDINIT (X_END+1)
#define X_MBDINIT (X_END+1)
#define X_UBDINIT (X_END+2)
#define X_ISA_BIO (X_END+1)
int dk_ndrive
, *dr_select
, hz
, kmemfd
, ndrives
;
kvm_read((void *)nl[x].n_value, (void *)&(v), sizeof(v))
#include "names.c" /* XXX */
static void cpustats
__P((void)), dkstats
__P((void)), phdr
__P((int));
static void usage
__P((void)), err
__P((const char *, ...));
int ch
, hdrcnt
, reps
, interval
, phz
, ndrives
;
char **cp
, *memfile
, *namelist
, buf
[30];
namelist
= memfile
= NULL
;
while ((ch
= getopt(argc
, argv
, "c:M:N:w:")) != EOF
)
if (kvm_openfiles(namelist
, memfile
, NULL
) == -1)
err("kvm_openfiles: %s", kvm_geterr());
err("kvm_nlist: %s", kvm_geterr());
if (nl
[X_DK_NDRIVE
].n_type
== 0)
err("dk_ndrive not found in namelist");
(void)nlread(X_DK_NDRIVE
, dk_ndrive
);
err("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
);
(void)nlread(X_PHZ
, phz
);
(void)kvm_read((void *)nl
[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
* The backward compatibility #ifdefs permit the syntax:
* iostat [ drives ] [ interval [ count ] ]
#define BACKWARD_COMPATIBILITY
for (ndrives
= 0; *argv
; ++argv
) {
#ifdef BACKWARD_COMPATIBILITY
for (i
= 0; i
< dk_ndrive
; i
++) {
if (strcmp(dr_name
[i
], *argv
))
#ifdef BACKWARD_COMPATIBILITY
for (i
= 0; i
< dk_ndrive
&& ndrives
< 4; i
++) {
if (dr_select
[i
] || dk_wpms
[i
] == 0)
for (cp
= defdrives
; *cp
; cp
++)
if (strcmp(dr_name
[i
], *cp
) == 0) {
for (i
= 0; i
< dk_ndrive
&& ndrives
< 4; i
++) {
(void)signal(SIGCONT
, phdr
);
(void)kvm_read((void *)nl
[X_DK_TIME
].n_value
,
cur
.dk_time
, dk_ndrive
* sizeof(long));
(void)kvm_read((void *)nl
[X_DK_XFER
].n_value
,
cur
.dk_xfer
, dk_ndrive
* sizeof(long));
(void)kvm_read((void *)nl
[X_DK_WDS
].n_value
,
cur
.dk_wds
, dk_ndrive
* sizeof(long));
(void)kvm_read((void *)nl
[X_DK_SEEK
].n_value
,
cur
.dk_seek
, dk_ndrive
* sizeof(long));
(void)kvm_read((void *)nl
[X_TK_NIN
].n_value
,
&cur
.tk_nin
, sizeof(cur
.tk_nin
));
(void)kvm_read((void *)nl
[X_TK_NOUT
].n_value
,
&cur
.tk_nout
, sizeof(cur
.tk_nout
));
(void)kvm_read((void *)nl
[X_CP_TIME
].n_value
,
cur
.cp_time
, sizeof(cur
.cp_time
));
for (i
= 0; i
< dk_ndrive
; i
++) {
#define X(fld) tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp
cur
.tk_nin
-= last
.tk_nin
;
cur
.tk_nout
-= last
.tk_nout
;
for (i
= 0; i
< CPUSTATES
; i
++) {
(void)printf("%4.0f%5.0f",
cur
.tk_nin
/ etime
, cur
.tk_nout
/ etime
);
if (reps
>= 0 && --reps
<= 0)
for (i
= 0; i
< dk_ndrive
; i
++)
(void)printf(" %3.3s ", dr_name
[i
]);
(void)printf(" cpu\n tin tout");
for (i
= 0; i
< dk_ndrive
; i
++)
(void)printf(" sps tps msps ");
(void)printf(" us ni sy id\n");
double atime
, itime
, msps
, words
, xtime
;
for (dn
= 0; dn
< dk_ndrive
; ++dn
) {
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 */
msps
= itime
* 1000 / cur
.dk_xfer
[dn
];
(void)printf("%5.1f ", msps
);
for (state
= 0; state
< CPUSTATES
; ++state
)
time
+= cur
.cp_time
[state
];
for (state
= 0; state
< CPUSTATES
; ++state
)
100. * cur
.cp_time
[state
] / (time
? time
: 1));
"usage: iostat [-c count] [-M core] [-N system] [-w wait] [drives]\n");
err(const char *fmt
, ...)
(void)fprintf(stderr
, "iostat: ");
(void)vfprintf(stderr
, fmt
, ap
);
(void)fprintf(stderr
, "\n");