* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)vmstat.c 5.8 (Berkeley) %G%";
#define X_MBDINIT (X_XSTATS+1)
#define X_UBDINIT (X_XSTATS+2)
#define X_VBDINIT (X_XSTATS+1)
#define X_CKEYSTATS (X_XSTATS+2)
#define X_DKEYSTATS (X_XSTATS+3)
char *defdrives
[] = { "hp0", "hp1", "hp2", 0 };
char *defdrives
[] = { 0 };
struct forkstat Forkstat
;
#define forkstat s.Forkstat
#define INTS(x) ((x) - (hz + phz))
int iter
, nintv
, iflag
= 0;
char *arg
, **cp
, buf
[BUFSIZ
];
fprintf(stderr
, "no /vmunix namelist\n");
mf
= open("/dev/kmem", 0);
fprintf(stderr
, "cannot open /dev/kmem\n");
while (argc
>0 && argv
[0][0]=='-') {
while (*++cp
) switch (*cp
) {
mf
= open("/dev/kmem", 2);
lseek(mf
, (long)nl
[X_SUM
].n_value
, L_SET
);
write(mf
, &z
.Sum
, sizeof z
.Sum
);
"usage: vmstat [ -fsi ] [ interval ] [ count]\n");
lseek(mf
, (long)nl
[X_FIRSTFREE
].n_value
, L_SET
);
read(mf
, &firstfree
, sizeof firstfree
);
lseek(mf
, (long)nl
[X_MAXFREE
].n_value
, L_SET
);
read(mf
, &maxfree
, sizeof maxfree
);
lseek(mf
, (long)nl
[X_BOOTTIME
].n_value
, L_SET
);
read(mf
, &boottime
, sizeof boottime
);
lseek(mf
, (long)nl
[X_HZ
].n_value
, L_SET
);
read(mf
, &hz
, sizeof hz
);
if (nl
[X_PHZ
].n_value
!= 0) {
lseek(mf
, (long)nl
[X_PHZ
].n_value
, L_SET
);
read(mf
, &phz
, sizeof phz
);
if (nl
[X_DK_NDRIVE
].n_value
== 0) {
fprintf(stderr
, "dk_ndrive undefined in system\n");
lseek(mf
, nl
[X_DK_NDRIVE
].n_value
, L_SET
);
read(mf
, &dk_ndrive
, sizeof (dk_ndrive
));
fprintf(stderr
, "dk_ndrive %d\n", dk_ndrive
);
dr_select
= (int *)calloc(dk_ndrive
, sizeof (int));
dr_name
= (char **)calloc(dk_ndrive
, sizeof (char *));
s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
s1./**/e = (t *)calloc(dk_ndrive, sizeof (t));
for (arg
= buf
, i
= 0; i
< dk_ndrive
; i
++) {
sprintf(dr_name
[i
], "dk%d", i
);
arg
+= strlen(dr_name
[i
]) + 1;
if (nintv
<= 0 || nintv
> 60*60*24*365*10) {
"Time makes no sense... namelist must be wrong.\n");
* Choose drives to be displayed. Priority
* goes to (in order) drives supplied as arguments,
* default drives. If everything isn't filled
* in and there are drives not taken care of,
* display the first few that fit.
while (argc
> 0 && !isdigit(argv
[0][0])) {
for (i
= 0; i
< dk_ndrive
; i
++) {
if (strcmp(dr_name
[i
], argv
[0]))
for (i
= 0; i
< dk_ndrive
&& ndrives
< 4; i
++) {
for (cp
= defdrives
; *cp
; cp
++)
if (strcmp(dr_name
[i
], *cp
) == 0) {
for (i
= 0; i
< dk_ndrive
&& ndrives
< 4; i
++) {
signal(SIGCONT
, printhdr
);
lseek(mf
, (long)nl
[X_CPTIME
].n_value
, L_SET
);
read(mf
, s
.time
, sizeof s
.time
);
lseek(mf
, (long)nl
[X_DKXFER
].n_value
, L_SET
);
read(mf
, s
.xfer
, dk_ndrive
* sizeof (long));
lseek(mf
, (long)nl
[X_SUM
].n_value
, L_SET
);
lseek(mf
, (long)nl
[X_RATE
].n_value
, L_SET
);
read(mf
, &rate
, sizeof rate
);
lseek(mf
, (long)nl
[X_TOTAL
].n_value
, L_SET
);
read(mf
, &total
, sizeof total
);
lseek(mf
, (long)nl
[X_SUM
].n_value
, L_SET
);
read(mf
, &sum
, sizeof sum
);
lseek(mf
, (long)nl
[X_DEFICIT
].n_value
, L_SET
);
read(mf
, &deficit
, sizeof deficit
);
for (i
=0; i
< dk_ndrive
; i
++) {
for (i
=0; i
< CPUSTATES
; i
++) {
printf("%2d%2d%2d", total
.t_rq
, total
.t_dw
+total
.t_pw
, total
.t_sw
);
#define pgtok(a) ((a)*NBPG/1024)
printf("%6d%6d", pgtok(total
.t_avm
), pgtok(total
.t_free
));
printf("%4d%3d", (rate
.v_pgrec
- (rate
.v_xsfrec
+rate
.v_xifrec
))/nintv
,
(rate
.v_xsfrec
+rate
.v_xifrec
)/nintv
);
printf("%4d", pgtok(rate
.v_pgpgin
)/nintv
);
printf("%4d%4d%4d%4d", pgtok(rate
.v_pgpgout
)/nintv
,
pgtok(rate
.v_dfree
)/nintv
, pgtok(deficit
), rate
.v_scan
/nintv
);
for (i
= 0; i
< dk_ndrive
; i
++)
printf("%4d%4d%4d", INTS(rate
.v_intr
/nintv
), rate
.v_syscall
/nintv
,
for(i
=0; i
<CPUSTATES
; i
++) {
if (i
== 0) { /* US+NI */
printf(" procs memory page ");
i
= (ndrives
* 3 - 6) / 2;
printf(" r b w avm fre re at pi po fr de sr ");
for (i
= 0; i
< dk_ndrive
; i
++)
printf("%c%c ", dr_name
[i
][0], dr_name
[i
][2]);
printf(" in sy cs us sy id\n");
lseek(mf
, (long)nl
[X_REC
].n_value
, L_SET
);
read(mf
, &s
.rectime
, sizeof s
.rectime
);
lseek(mf
, (long)nl
[X_PGIN
].n_value
, L_SET
);
read(mf
, &s
.pgintime
, sizeof s
.pgintime
);
lseek(mf
, (long)nl
[X_SUM
].n_value
, L_SET
);
read(mf
, &sum
, sizeof sum
);
printf("%d reclaims, %d total time (usec)\n", sum
.v_pgrec
, s
.rectime
);
printf("average: %d usec / reclaim\n", s
.rectime
/sum
.v_pgrec
);
printf("%d page ins, %d total time (msec)\n",sum
.v_pgin
, s
.pgintime
/10);
printf("average: %8.1f msec / page in\n", s
.pgintime
/(sum
.v_pgin
*10.0));
struct nchstats nchstats
;
struct keystats keystats
;
lseek(mf
, (long)nl
[X_SUM
].n_value
, L_SET
);
read(mf
, &sum
, sizeof sum
);
printf("%9d swap ins\n", sum
.v_swpin
);
printf("%9d swap outs\n", sum
.v_swpout
);
printf("%9d pages swapped in\n", sum
.v_pswpin
/ CLSIZE
);
printf("%9d pages swapped out\n", sum
.v_pswpout
/ CLSIZE
);
printf("%9d total address trans. faults taken\n", sum
.v_faults
);
printf("%9d page ins\n", sum
.v_pgin
);
printf("%9d page outs\n", sum
.v_pgout
);
printf("%9d pages paged in\n", sum
.v_pgpgin
);
printf("%9d pages paged out\n", sum
.v_pgpgout
);
printf("%9d sequential process pages freed\n", sum
.v_seqfree
);
printf("%9d total reclaims (%d%% fast)\n", sum
.v_pgrec
,
pct(sum
.v_fastpgrec
, sum
.v_pgrec
));
printf("%9d reclaims from free list\n", sum
.v_pgfrec
);
printf("%9d intransit blocking page faults\n", sum
.v_intrans
);
printf("%9d zero fill pages created\n", sum
.v_nzfod
/ CLSIZE
);
printf("%9d zero fill page faults\n", sum
.v_zfod
/ CLSIZE
);
printf("%9d executable fill pages created\n", sum
.v_nexfod
/ CLSIZE
);
printf("%9d executable fill page faults\n", sum
.v_exfod
/ CLSIZE
);
printf("%9d swap text pages found in free list\n", sum
.v_xsfrec
);
printf("%9d inode text pages found in free list\n", sum
.v_xifrec
);
printf("%9d file fill pages created\n", sum
.v_nvrfod
/ CLSIZE
);
printf("%9d file fill page faults\n", sum
.v_vrfod
/ CLSIZE
);
printf("%9d pages examined by the clock daemon\n", sum
.v_scan
);
printf("%9d revolutions of the clock hand\n", sum
.v_rev
);
printf("%9d pages freed by the clock daemon\n", sum
.v_dfree
/ CLSIZE
);
printf("%9d cpu context switches\n", sum
.v_swtch
);
printf("%9d device interrupts\n", sum
.v_intr
);
printf("%9d software interrupts\n", sum
.v_soft
);
printf("%9d pseudo-dma dz interrupts\n", sum
.v_pdma
);
printf("%9d traps\n", sum
.v_trap
);
printf("%9d system calls\n", sum
.v_syscall
);
lseek(mf
, (long)nl
[X_NCHSTATS
].n_value
, 0);
read(mf
, &nchstats
, sizeof nchstats
);
nchtotal
= nchstats
.ncs_goodhits
+ nchstats
.ncs_badhits
+
nchstats
.ncs_falsehits
+ nchstats
.ncs_miss
+ nchstats
.ncs_long
;
printf("%9d total name lookups", nchtotal
);
printf(" (cache hits %d%% system %d%% per-process)\n",
pct(nchstats
.ncs_goodhits
, nchtotal
),
pct(nchstats
.ncs_pass2
, nchtotal
));
printf("%9s badhits %d, falsehits %d, toolong %d\n", "",
nchstats
.ncs_badhits
, nchstats
.ncs_falsehits
, nchstats
.ncs_long
);
lseek(mf
, (long)nl
[X_XSTATS
].n_value
, 0);
read(mf
, &xstats
, sizeof xstats
);
printf("%9d total calls to xalloc (cache hits %d%%)\n",
xstats
.alloc
, pct(xstats
.alloc_cachehit
, xstats
.alloc
));
printf("%9s sticky %d flushed %d unused %d\n", "",
xstats
.alloc_inuse
, xstats
.alloc_cacheflush
, xstats
.alloc_unused
);
printf("%9d total calls to xfree", xstats
.free
);
printf(" (sticky %d cached %d swapped %d)\n",
xstats
.free_inuse
, xstats
.free_cache
, xstats
.free_cacheswap
);
lseek(mf
, (long)nl
[X_CKEYSTATS
].n_value
, 0);
read(mf
, &keystats
, sizeof keystats
);
printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
keystats
.ks_allocs
, "code cache keys allocated",
pct(keystats
.ks_free
, keystats
.ks_allocs
),
pct(keystats
.ks_norefs
, keystats
.ks_allocs
),
pct(keystats
.ks_taken
, keystats
.ks_allocs
),
pct(keystats
.ks_shared
, keystats
.ks_allocs
));
lseek(mf
, (long)nl
[X_DKEYSTATS
].n_value
, 0);
read(mf
, &keystats
, sizeof keystats
);
printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
keystats
.ks_allocs
, "data cache keys allocated",
pct(keystats
.ks_free
, keystats
.ks_allocs
),
pct(keystats
.ks_norefs
, keystats
.ks_allocs
),
pct(keystats
.ks_taken
, keystats
.ks_allocs
),
pct(keystats
.ks_shared
, keystats
.ks_allocs
));
lseek(mf
, (long)nl
[X_FORKSTAT
].n_value
, L_SET
);
read(mf
, &forkstat
, sizeof forkstat
);
printf("%d forks, %d pages, average=%.2f\n",
forkstat
.cntfork
, forkstat
.sizfork
,
(float) forkstat
.sizfork
/ forkstat
.cntfork
);
printf("%d vforks, %d pages, average=%.2f\n",
forkstat
.cntvfork
, forkstat
.sizvfork
,
(float)forkstat
.sizvfork
/ forkstat
.cntvfork
);
printf("%3.0f", s
.xfer
[dn
]/etime
);
for(i
=0; i
<CPUSTATES
; i
++)
return(s
.time
[row
]*100./t
);
return ((top
* 100) / bot
);
char *intrname
, *malloc();
nintr
= (nl
[X_EINTRCNT
].n_value
- nl
[X_INTRCNT
].n_value
) / sizeof(long);
intrcnt
= (long *) malloc(nl
[X_EINTRCNT
].n_value
-
intrname
= malloc(nl
[X_EINTRNAMES
].n_value
- nl
[X_INTRNAMES
].n_value
);
if (intrcnt
== NULL
|| intrname
== NULL
) {
fprintf(stderr
, "vmstat: out of memory\n");
lseek(mf
, (long)nl
[X_INTRCNT
].n_value
, L_SET
);
read(mf
, intrcnt
, nintr
* sizeof (long));
lseek(mf
, (long)nl
[X_INTRNAMES
].n_value
, L_SET
);
read(mf
, intrname
, nl
[X_EINTRNAMES
].n_value
- nl
[X_INTRNAMES
].n_value
);
printf("interrupt total rate\n");
printf("%-12s %8ld %8ld\n", intrname
,
*intrcnt
, *intrcnt
/ nintv
);
intrname
+= strlen(intrname
) + 1;
printf("Total %8ld %8ld\n", inttotal
, inttotal
/ nintv
);
#define steal(where, var) \
lseek(mf, where, L_SET); read(mf, &var, sizeof var);
* Read the drive names out of kmem.
#include <vaxuba/ubavar.h>
#include <vaxmba/mbavar.h>
register struct mba_device
*mp
;
char *cp
= (char *) &two_char
;
struct uba_device udev
, *up
;
mp
= (struct mba_device
*) nl
[X_MBDINIT
].n_value
;
up
= (struct uba_device
*) nl
[X_UBDINIT
].n_value
;
fprintf(stderr
, "vmstat: Disk init info not in namelist\n");
if (mdev
.mi_dk
< 0 || mdev
.mi_alive
== 0)
steal(mdev
.mi_driver
, mdrv
);
steal(mdrv
.md_dname
, two_char
);
sprintf(dr_name
[mdev
.mi_dk
], "%c%c%d",
cp
[0], cp
[1], mdev
.mi_unit
);
if (udev
.ui_dk
< 0 || udev
.ui_alive
== 0)
steal(udev
.ui_driver
, udrv
);
steal(udrv
.ud_dname
, two_char
);
sprintf(dr_name
[udev
.ui_dk
], "%c%c%d",
cp
[0], cp
[1], udev
.ui_unit
);
#include <tahoevba/vbavar.h>
* Read the drive names out of kmem.
struct vba_device udev
, *up
;
char *cp
= (char *)&two_char
;
up
= (struct vba_device
*) nl
[X_VBDINIT
].n_value
;
fprintf(stderr
, "vmstat: Disk init info not in namelist\n");
if (udev
.ui_dk
< 0 || udev
.ui_alive
== 0)
steal(udev
.ui_driver
, udrv
);
steal(udrv
.ud_dname
, two_char
);
sprintf(dr_name
[udev
.ui_dk
], "%c%c%d",
cp
[0], cp
[1], udev
.ui_unit
);