]>
git.saurik.com Git - apple/system_cmds.git/blob - iostat.tproj/iostat.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1986, 1991, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 static char copyright
[] =
59 "@(#) Copyright (c) 1986, 1991, 1993\n\
60 The Regents of the University of California. All rights reserved.\n";
64 static char sccsid
[] = "@(#)iostat.c 8.3 (Berkeley) 4/28/95";
67 #include <sys/param.h>
69 #include <sys/dkstat.h>
84 struct nlist namelist
[] = {
105 #define X_DK_NDRIVE 10
108 #if defined(hp300) || defined(luna68k)
109 #define X_HPDINIT (X_END+1)
113 #define X_SCSI_DINIT (X_END+1)
117 #define X_VBDINIT (X_END+1)
122 #define X_MBDINIT (X_END+1)
124 #define X_UBDINIT (X_END+2)
130 long cp_time
[CPUSTATES
];
142 int dk_ndrive
, *dr_select
, hz
, kmemfd
, ndrives
;
145 #define nlread(x, v) \
146 kvm_read(kd, namelist[x].n_value, &(v), sizeof(v))
148 #include "names.c" /* XXX */
150 void cpustats
__P((void));
151 void dkstats
__P((void));
152 void phdr
__P((int));
153 void usage
__P((void));
162 int ch
, hdrcnt
, reps
, interval
, stathz
, ndrives
;
163 char **cp
, *memf
, *nlistf
, buf
[30];
164 char errbuf
[_POSIX2_LINE_MAX
];
167 nlistf
= memf
= NULL
;
168 while ((ch
= getopt(argc
, argv
, "c:M:N:w:")) != EOF
)
171 if ((reps
= atoi(optarg
)) <= 0)
172 errx(1, "repetition count <= 0.");
181 if ((interval
= atoi(optarg
)) <= 0)
182 errx(1, "interval <= 0.");
192 * Discard setgid privileges if not the running kernel so that bad
193 * guys can't print interesting stuff from kernel memory.
195 if (nlistf
!= NULL
|| memf
!= NULL
)
198 kd
= kvm_openfiles(nlistf
, memf
, NULL
, O_RDONLY
, errbuf
);
200 errx(1, "kvm_openfiles: %s", errbuf
);
201 if (kvm_nlist(kd
, namelist
) == -1)
202 errx(1, "kvm_nlist: %s", kvm_geterr(kd
));
203 if (namelist
[X_DK_NDRIVE
].n_type
== 0)
204 errx(1, "dk_ndrive not found in namelist");
205 (void)nlread(X_DK_NDRIVE
, dk_ndrive
);
207 errx(1, "invalid dk_ndrive %d\n", dk_ndrive
);
209 cur
.dk_time
= calloc(dk_ndrive
, sizeof(long));
210 cur
.dk_wds
= calloc(dk_ndrive
, sizeof(long));
211 cur
.dk_seek
= calloc(dk_ndrive
, sizeof(long));
212 cur
.dk_xfer
= calloc(dk_ndrive
, sizeof(long));
213 last
.dk_time
= calloc(dk_ndrive
, sizeof(long));
214 last
.dk_wds
= calloc(dk_ndrive
, sizeof(long));
215 last
.dk_seek
= calloc(dk_ndrive
, sizeof(long));
216 last
.dk_xfer
= calloc(dk_ndrive
, sizeof(long));
217 dr_select
= calloc(dk_ndrive
, sizeof(int));
218 dr_name
= calloc(dk_ndrive
, sizeof(char *));
219 dk_wpms
= calloc(dk_ndrive
, sizeof(long));
221 for (i
= 0; i
< dk_ndrive
; i
++) {
222 (void)sprintf(buf
, "dk%d", i
);
223 dr_name
[i
] = strdup(buf
);
227 (void)nlread(X_HZ
, hz
);
228 (void)nlread(X_STATHZ
, stathz
);
231 (void)kvm_read(kd
, namelist
[X_DK_WPMS
].n_value
, dk_wpms
,
232 dk_ndrive
* sizeof(dk_wpms
));
235 * Choose drives to be displayed. Priority goes to (in order) drives
236 * supplied as arguments and default drives. If everything isn't
237 * filled in and there are drives not taken care of, display the first
240 * The backward compatibility #ifdefs permit the syntax:
241 * iostat [ drives ] [ interval [ count ] ]
243 #define BACKWARD_COMPATIBILITY
244 for (ndrives
= 0; *argv
; ++argv
) {
245 #ifdef BACKWARD_COMPATIBILITY
249 for (i
= 0; i
< dk_ndrive
; i
++) {
250 if (strcmp(dr_name
[i
], *argv
))
256 #ifdef BACKWARD_COMPATIBILITY
258 interval
= atoi(*argv
);
271 for (i
= 0; i
< dk_ndrive
&& ndrives
< 4; i
++) {
272 if (dr_select
[i
] || dk_wpms
[i
] == 0)
274 for (cp
= defdrives
; *cp
; cp
++)
275 if (strcmp(dr_name
[i
], *cp
) == 0) {
281 for (i
= 0; i
< dk_ndrive
&& ndrives
< 4; i
++) {
288 (void)signal(SIGCONT
, phdr
);
295 (void)kvm_read(kd
, namelist
[X_DK_TIME
].n_value
,
296 cur
.dk_time
, dk_ndrive
* sizeof(long));
297 (void)kvm_read(kd
, namelist
[X_DK_XFER
].n_value
,
298 cur
.dk_xfer
, dk_ndrive
* sizeof(long));
299 (void)kvm_read(kd
, namelist
[X_DK_WDS
].n_value
,
300 cur
.dk_wds
, dk_ndrive
* sizeof(long));
301 (void)kvm_read(kd
, namelist
[X_DK_SEEK
].n_value
,
302 cur
.dk_seek
, dk_ndrive
* sizeof(long));
303 (void)kvm_read(kd
, namelist
[X_TK_NIN
].n_value
,
304 &cur
.tk_nin
, sizeof(cur
.tk_nin
));
305 (void)kvm_read(kd
, namelist
[X_TK_NOUT
].n_value
,
306 &cur
.tk_nout
, sizeof(cur
.tk_nout
));
307 (void)kvm_read(kd
, namelist
[X_CP_TIME
].n_value
,
308 cur
.cp_time
, sizeof(cur
.cp_time
));
309 for (i
= 0; i
< dk_ndrive
; i
++) {
312 #define X(fld) tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp
319 cur
.tk_nin
-= last
.tk_nin
;
322 cur
.tk_nout
-= last
.tk_nout
;
325 for (i
= 0; i
< CPUSTATES
; i
++) {
327 etime
+= cur
.cp_time
[i
];
332 (void)printf("%4.0f%5.0f",
333 cur
.tk_nin
/ etime
, cur
.tk_nout
/ etime
);
337 (void)fflush(stdout
);
339 if (reps
>= 0 && --reps
<= 0)
341 (void)sleep(interval
);
353 (void)printf(" tty");
354 for (i
= 0; i
< dk_ndrive
; i
++)
356 (void)printf(" %3.3s ", dr_name
[i
]);
357 (void)printf(" cpu\n tin tout");
358 for (i
= 0; i
< dk_ndrive
; i
++)
360 (void)printf(" sps tps msps ");
361 (void)printf(" us ni sy in id\n");
368 double atime
, itime
, msps
, words
, xtime
;
370 for (dn
= 0; dn
< dk_ndrive
; ++dn
) {
373 words
= cur
.dk_wds
[dn
] * 32; /* words xfer'd */
374 (void)printf("%4.0f", /* sectors */
375 words
/ (DEV_BSIZE
/ 2) / etime
);
377 (void)printf("%4.0f", cur
.dk_xfer
[dn
] / etime
);
379 if (dk_wpms
[dn
] && cur
.dk_xfer
[dn
]) {
380 atime
= cur
.dk_time
[dn
]; /* ticks disk busy */
381 atime
/= (float)hz
; /* ticks to seconds */
382 xtime
= words
/ dk_wpms
[dn
]; /* transfer time */
383 itime
= atime
- xtime
; /* time not xfer'ing */
387 msps
= itime
* 1000 / cur
.dk_xfer
[dn
];
390 (void)printf("%5.1f ", msps
);
401 for (state
= 0; state
< CPUSTATES
; ++state
)
402 time
+= cur
.cp_time
[state
];
403 for (state
= 0; state
< CPUSTATES
; ++state
)
404 (void)printf("%3.0f",
405 100. * cur
.cp_time
[state
] / (time
? time
: 1));
411 (void)fprintf(stderr
,
412 "usage: iostat [-c count] [-M core] [-N system] [-w wait] [drives]\n");