* Copyright (c) 1986, 1991 The Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1986, 1991 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)iostat.c 5.8 (Berkeley) %G%";
#define X_HPDINIT (X_END+1)
#define X_VBDINIT (X_END+1)
#define X_MBDINIT (X_END+1)
#define X_UBDINIT (X_END+2)
int dk_ndrive
, *dr_select
, hz
, kmemfd
, ndrives
;
#include "names.c" /* XXX */
kvm_read((void *)nl[x].n_value, (void *)&(v), sizeof(v))
int ch
, hdrcnt
, reps
, interval
, phz
, ndrives
;
char **cp
, *memfile
, *namelist
, buf
[30];
void cpustats(), dkstats(), phdr(), read_names(), usage(), error();
namelist
= memfile
= NULL
;
while ((ch
= getopt(argc
, argv
, "c:M:N:w:")) != EOF
)
if (kvm_openfiles(namelist
, memfile
, NULL
) == -1) {
error("kvm_openfiles: %s", kvm_geterr());
if (kvm_nlist(nl
) == -1) {
error("kvm_nlist: %s", kvm_geterr());
if (nl
[X_DK_BUSY
].n_type
== 0) {
error("dk_busy not found namelist");
if (nl
[X_DK_NDRIVE
].n_type
== 0) {
error("dk_ndrive not found in namelist");
(void)nlread(X_DK_NDRIVE
, dk_ndrive
);
error("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)nlread(X_DK_BUSY
, cur
.dk_busy
);
(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");
(void)fprintf(stderr
, "iostat: ");
(void)vfprintf(stderr
, fmt
, ap
);
(void)fprintf(stderr
, "\n");