1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* 7*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 8*7c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 9*7c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 10*7c478bd9Sstevel@tonic-gate */ 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 13*7c478bd9Sstevel@tonic-gate 14*7c478bd9Sstevel@tonic-gate /* from UCB 5.4 5/17/86 */ 15*7c478bd9Sstevel@tonic-gate /* from SunOS 4.1, SID 1.31 */ 16*7c478bd9Sstevel@tonic-gate 17*7c478bd9Sstevel@tonic-gate #include <stdio.h> 18*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 19*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 20*7c478bd9Sstevel@tonic-gate #include <ctype.h> 21*7c478bd9Sstevel@tonic-gate #include <unistd.h> 22*7c478bd9Sstevel@tonic-gate #include <memory.h> 23*7c478bd9Sstevel@tonic-gate #include <string.h> 24*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 25*7c478bd9Sstevel@tonic-gate #include <errno.h> 26*7c478bd9Sstevel@tonic-gate #include <signal.h> 27*7c478bd9Sstevel@tonic-gate #include <values.h> 28*7c478bd9Sstevel@tonic-gate #include <poll.h> 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #include "statcommon.h" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate char cmdname[] = "vmstat"; 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate static int hz; 35*7c478bd9Sstevel@tonic-gate static int pagesize; 36*7c478bd9Sstevel@tonic-gate static double etime; 37*7c478bd9Sstevel@tonic-gate static int lines = 1; 38*7c478bd9Sstevel@tonic-gate static int swflag = 0, cflag = 0, pflag = 0; 39*7c478bd9Sstevel@tonic-gate static int suppress_state; 40*7c478bd9Sstevel@tonic-gate static long iter = 0; 41*7c478bd9Sstevel@tonic-gate static int poll_interval = 0; 42*7c478bd9Sstevel@tonic-gate static struct snapshot *ss; 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate struct iodev_filter df; 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #define pgtok(a) ((a) * (pagesize >> 10)) 47*7c478bd9Sstevel@tonic-gate #define denom(x) ((x) ? (x) : 1) 48*7c478bd9Sstevel@tonic-gate #define REPRINT 19 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate static void dovmstats(struct snapshot *old, struct snapshot *new); 51*7c478bd9Sstevel@tonic-gate static void printhdr(int); 52*7c478bd9Sstevel@tonic-gate static void dosum(struct sys_snapshot *ss); 53*7c478bd9Sstevel@tonic-gate static void dointr(struct snapshot *ss); 54*7c478bd9Sstevel@tonic-gate static void docachestats(kstat_ctl_t *kc); 55*7c478bd9Sstevel@tonic-gate static void usage(void); 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate int 58*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 59*7c478bd9Sstevel@tonic-gate { 60*7c478bd9Sstevel@tonic-gate struct snapshot *old = NULL; 61*7c478bd9Sstevel@tonic-gate enum snapshot_types types = SNAP_SYSTEM; 62*7c478bd9Sstevel@tonic-gate int summary = 0; 63*7c478bd9Sstevel@tonic-gate int intr = 0; 64*7c478bd9Sstevel@tonic-gate kstat_ctl_t *kc; 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate pagesize = sysconf(_SC_PAGESIZE); 67*7c478bd9Sstevel@tonic-gate hz = sysconf(_SC_CLK_TCK); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate argc--, argv++; 70*7c478bd9Sstevel@tonic-gate while (argc > 0 && argv[0][0] == '-') { 71*7c478bd9Sstevel@tonic-gate char *cp = *argv++; 72*7c478bd9Sstevel@tonic-gate argc--; 73*7c478bd9Sstevel@tonic-gate while (*++cp) { 74*7c478bd9Sstevel@tonic-gate switch (*cp) { 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate case 'S': 77*7c478bd9Sstevel@tonic-gate swflag = !swflag; 78*7c478bd9Sstevel@tonic-gate break; 79*7c478bd9Sstevel@tonic-gate case 's': 80*7c478bd9Sstevel@tonic-gate summary = 1; 81*7c478bd9Sstevel@tonic-gate break; 82*7c478bd9Sstevel@tonic-gate case 'i': 83*7c478bd9Sstevel@tonic-gate intr = 1; 84*7c478bd9Sstevel@tonic-gate break; 85*7c478bd9Sstevel@tonic-gate case 'c': 86*7c478bd9Sstevel@tonic-gate cflag++; 87*7c478bd9Sstevel@tonic-gate break; 88*7c478bd9Sstevel@tonic-gate case 'q': 89*7c478bd9Sstevel@tonic-gate suppress_state = 1; 90*7c478bd9Sstevel@tonic-gate break; 91*7c478bd9Sstevel@tonic-gate case 'p': 92*7c478bd9Sstevel@tonic-gate pflag++; /* detailed paging info */ 93*7c478bd9Sstevel@tonic-gate break; 94*7c478bd9Sstevel@tonic-gate default: 95*7c478bd9Sstevel@tonic-gate usage(); 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate /* consistency with iostat */ 101*7c478bd9Sstevel@tonic-gate types |= SNAP_CPUS; 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate if (intr) 104*7c478bd9Sstevel@tonic-gate types |= SNAP_INTERRUPTS; 105*7c478bd9Sstevel@tonic-gate if (cflag) 106*7c478bd9Sstevel@tonic-gate types |= SNAP_FLUSHES; 107*7c478bd9Sstevel@tonic-gate if (!intr) 108*7c478bd9Sstevel@tonic-gate types |= SNAP_IODEVS; 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* max to fit in less than 80 characters */ 111*7c478bd9Sstevel@tonic-gate df.if_max_iodevs = 4; 112*7c478bd9Sstevel@tonic-gate df.if_allowed_types = IODEV_DISK; 113*7c478bd9Sstevel@tonic-gate df.if_nr_names = 0; 114*7c478bd9Sstevel@tonic-gate df.if_names = safe_alloc(df.if_max_iodevs * sizeof (char *)); 115*7c478bd9Sstevel@tonic-gate (void) memset(df.if_names, 0, df.if_max_iodevs * sizeof (char *)); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate while (argc > 0 && !isdigit(argv[0][0]) && 118*7c478bd9Sstevel@tonic-gate df.if_nr_names < df.if_max_iodevs) { 119*7c478bd9Sstevel@tonic-gate df.if_names[df.if_nr_names] = *argv; 120*7c478bd9Sstevel@tonic-gate df.if_nr_names++; 121*7c478bd9Sstevel@tonic-gate argc--, argv++; 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate kc = open_kstat(); 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate ss = acquire_snapshot(kc, types, &df); 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /* time, in seconds, since boot */ 129*7c478bd9Sstevel@tonic-gate etime = ss->s_sys.ss_ticks / hz; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (intr) { 132*7c478bd9Sstevel@tonic-gate dointr(ss); 133*7c478bd9Sstevel@tonic-gate free_snapshot(ss); 134*7c478bd9Sstevel@tonic-gate exit(0); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate if (summary) { 137*7c478bd9Sstevel@tonic-gate dosum(&ss->s_sys); 138*7c478bd9Sstevel@tonic-gate free_snapshot(ss); 139*7c478bd9Sstevel@tonic-gate exit(0); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (argc > 0) { 143*7c478bd9Sstevel@tonic-gate long interval; 144*7c478bd9Sstevel@tonic-gate char *endptr; 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate errno = 0; 147*7c478bd9Sstevel@tonic-gate interval = strtol(argv[0], &endptr, 10); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate if (errno > 0 || *endptr != '\0' || interval <= 0 || 150*7c478bd9Sstevel@tonic-gate interval > MAXINT) 151*7c478bd9Sstevel@tonic-gate usage(); 152*7c478bd9Sstevel@tonic-gate poll_interval = 1000 * interval; 153*7c478bd9Sstevel@tonic-gate if (poll_interval <= 0) 154*7c478bd9Sstevel@tonic-gate usage(); 155*7c478bd9Sstevel@tonic-gate iter = MAXLONG; 156*7c478bd9Sstevel@tonic-gate if (argc > 1) { 157*7c478bd9Sstevel@tonic-gate iter = strtol(argv[1], NULL, 10); 158*7c478bd9Sstevel@tonic-gate if (errno > 0 || *endptr != '\0' || iter <= 0) 159*7c478bd9Sstevel@tonic-gate usage(); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate if (argc > 2) 162*7c478bd9Sstevel@tonic-gate usage(); 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate if (cflag) { 166*7c478bd9Sstevel@tonic-gate free_snapshot(ss); 167*7c478bd9Sstevel@tonic-gate docachestats(kc); 168*7c478bd9Sstevel@tonic-gate exit(0); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate (void) sigset(SIGCONT, printhdr); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate printhdr(0); 174*7c478bd9Sstevel@tonic-gate dovmstats(old, ss); 175*7c478bd9Sstevel@tonic-gate while (--iter > 0) { 176*7c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, poll_interval); 177*7c478bd9Sstevel@tonic-gate free_snapshot(old); 178*7c478bd9Sstevel@tonic-gate old = ss; 179*7c478bd9Sstevel@tonic-gate ss = acquire_snapshot(kc, types, &df); 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate if (!suppress_state) 182*7c478bd9Sstevel@tonic-gate snapshot_report_changes(old, ss); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* if config changed, show stats from boot */ 185*7c478bd9Sstevel@tonic-gate if (snapshot_has_changed(old, ss)) { 186*7c478bd9Sstevel@tonic-gate free_snapshot(old); 187*7c478bd9Sstevel@tonic-gate old = NULL; 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate dovmstats(old, ss); 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate free_snapshot(old); 194*7c478bd9Sstevel@tonic-gate free_snapshot(ss); 195*7c478bd9Sstevel@tonic-gate free(df.if_names); 196*7c478bd9Sstevel@tonic-gate (void) kstat_close(kc); 197*7c478bd9Sstevel@tonic-gate return (0); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate #define DELTA(v) (new->v - (old ? old->v : 0)) 201*7c478bd9Sstevel@tonic-gate #define ADJ(n) ((adj <= 0) ? n : (adj >= n) ? 1 : n - adj) 202*7c478bd9Sstevel@tonic-gate #define adjprintf(fmt, n, val) adj -= (n + 1) - printf(fmt, ADJ(n), val) 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate static int adj; /* number of excess columns */ 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 207*7c478bd9Sstevel@tonic-gate static void 208*7c478bd9Sstevel@tonic-gate show_disk(void *v1, void *v2, void *d) 209*7c478bd9Sstevel@tonic-gate { 210*7c478bd9Sstevel@tonic-gate struct iodev_snapshot *old = (struct iodev_snapshot *)v1; 211*7c478bd9Sstevel@tonic-gate struct iodev_snapshot *new = (struct iodev_snapshot *)v2; 212*7c478bd9Sstevel@tonic-gate hrtime_t oldtime = new->is_crtime; 213*7c478bd9Sstevel@tonic-gate double hr_etime; 214*7c478bd9Sstevel@tonic-gate double reads, writes; 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate if (new == NULL) 217*7c478bd9Sstevel@tonic-gate return; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate if (old) 220*7c478bd9Sstevel@tonic-gate oldtime = old->is_stats.wlastupdate; 221*7c478bd9Sstevel@tonic-gate hr_etime = new->is_stats.wlastupdate - oldtime; 222*7c478bd9Sstevel@tonic-gate if (hr_etime == 0.0) 223*7c478bd9Sstevel@tonic-gate hr_etime = NANOSEC; 224*7c478bd9Sstevel@tonic-gate reads = new->is_stats.reads - (old ? old->is_stats.reads : 0); 225*7c478bd9Sstevel@tonic-gate writes = new->is_stats.writes - (old ? old->is_stats.writes : 0); 226*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, (reads + writes) / hr_etime * NANOSEC); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate static void 230*7c478bd9Sstevel@tonic-gate dovmstats(struct snapshot *old, struct snapshot *new) 231*7c478bd9Sstevel@tonic-gate { 232*7c478bd9Sstevel@tonic-gate kstat_t *oldsys = NULL; 233*7c478bd9Sstevel@tonic-gate kstat_t *newsys = &new->s_sys.ss_agg_sys; 234*7c478bd9Sstevel@tonic-gate kstat_t *oldvm = NULL; 235*7c478bd9Sstevel@tonic-gate kstat_t *newvm = &new->s_sys.ss_agg_vm; 236*7c478bd9Sstevel@tonic-gate double percent_factor; 237*7c478bd9Sstevel@tonic-gate ulong_t updates; 238*7c478bd9Sstevel@tonic-gate int count; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate adj = 0; 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate if (old) { 243*7c478bd9Sstevel@tonic-gate oldsys = &old->s_sys.ss_agg_sys; 244*7c478bd9Sstevel@tonic-gate oldvm = &old->s_sys.ss_agg_vm; 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate etime = cpu_ticks_delta(oldsys, newsys); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate percent_factor = 100.0 / denom(etime); 250*7c478bd9Sstevel@tonic-gate /* 251*7c478bd9Sstevel@tonic-gate * If any time has passed, convert etime to seconds per CPU 252*7c478bd9Sstevel@tonic-gate */ 253*7c478bd9Sstevel@tonic-gate etime = etime >= 1.0 ? (etime / nr_active_cpus(new)) / hz : 1.0; 254*7c478bd9Sstevel@tonic-gate updates = denom(DELTA(s_sys.ss_sysinfo.updates)); 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate if (--lines == 0) 257*7c478bd9Sstevel@tonic-gate printhdr(0); 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate adj = 0; 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate if (pflag) { 262*7c478bd9Sstevel@tonic-gate adjprintf(" %*u", 6, 263*7c478bd9Sstevel@tonic-gate pgtok((int)(DELTA(s_sys.ss_vminfo.swap_avail) / updates))); 264*7c478bd9Sstevel@tonic-gate adjprintf(" %*u", 5, 265*7c478bd9Sstevel@tonic-gate pgtok((int)(DELTA(s_sys.ss_vminfo.freemem) / updates))); 266*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, kstat_delta(oldvm, newvm, "pgrec") 267*7c478bd9Sstevel@tonic-gate / etime); 268*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, (kstat_delta(oldvm, newvm, "hat_fault") + 269*7c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "as_fault")) / etime); 270*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, pgtok(kstat_delta(oldvm, newvm, "dfree")) 271*7c478bd9Sstevel@tonic-gate / etime); 272*7c478bd9Sstevel@tonic-gate adjprintf(" %*ld", 3, pgtok(new->s_sys.ss_deficit)); 273*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, kstat_delta(oldvm, newvm, "scan") 274*7c478bd9Sstevel@tonic-gate / etime); 275*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 276*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execpgin")) / etime); 277*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 278*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execpgout")) / etime); 279*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 280*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execfree")) / etime); 281*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 282*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonpgin")) / etime); 283*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 284*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonpgout")) / etime); 285*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 286*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonfree")) / etime); 287*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 288*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fspgin")) / etime); 289*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 290*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fspgout")) / etime); 291*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f\n", 4, 292*7c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fsfree")) / etime); 293*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 294*7c478bd9Sstevel@tonic-gate return; 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.runque) / updates); 298*7c478bd9Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.waiting) / updates); 299*7c478bd9Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.swpque) / updates); 300*7c478bd9Sstevel@tonic-gate adjprintf(" %*u", 6, pgtok((int)(DELTA(s_sys.ss_vminfo.swap_avail) 301*7c478bd9Sstevel@tonic-gate / updates))); 302*7c478bd9Sstevel@tonic-gate adjprintf(" %*u", 5, pgtok((int)(DELTA(s_sys.ss_vminfo.freemem) 303*7c478bd9Sstevel@tonic-gate / updates))); 304*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, swflag? 305*7c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "swapin") / etime : 306*7c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "pgrec") / etime); 307*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, swflag? 308*7c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "swapout") / etime : 309*7c478bd9Sstevel@tonic-gate (kstat_delta(oldvm, newvm, "hat_fault") 310*7c478bd9Sstevel@tonic-gate + kstat_delta(oldvm, newvm, "as_fault")) 311*7c478bd9Sstevel@tonic-gate / etime); 312*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "pgpgin")) 313*7c478bd9Sstevel@tonic-gate / etime); 314*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "pgpgout")) 315*7c478bd9Sstevel@tonic-gate / etime); 316*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "dfree")) 317*7c478bd9Sstevel@tonic-gate / etime); 318*7c478bd9Sstevel@tonic-gate adjprintf(" %*ld", 2, pgtok(new->s_sys.ss_deficit)); 319*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, kstat_delta(oldvm, newvm, "scan") / etime); 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate (void) snapshot_walk(SNAP_IODEVS, old, new, show_disk, NULL); 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate count = df.if_max_iodevs - new->s_nr_iodevs; 324*7c478bd9Sstevel@tonic-gate while (count-- > 0) 325*7c478bd9Sstevel@tonic-gate adjprintf(" %*d", 2, 0); 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "intr") / etime); 328*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "syscall") / etime); 329*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "pswitch") / etime); 330*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, 331*7c478bd9Sstevel@tonic-gate kstat_delta(oldsys, newsys, "cpu_ticks_user") * percent_factor); 332*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, kstat_delta(oldsys, newsys, "cpu_ticks_kernel") 333*7c478bd9Sstevel@tonic-gate * percent_factor); 334*7c478bd9Sstevel@tonic-gate adjprintf(" %*.0f\n", 2, (kstat_delta(oldsys, newsys, "cpu_ticks_idle") 335*7c478bd9Sstevel@tonic-gate + kstat_delta(oldsys, newsys, "cpu_ticks_wait")) 336*7c478bd9Sstevel@tonic-gate * percent_factor); 337*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 341*7c478bd9Sstevel@tonic-gate static void 342*7c478bd9Sstevel@tonic-gate print_disk(void *v, void *v2, void *d) 343*7c478bd9Sstevel@tonic-gate { 344*7c478bd9Sstevel@tonic-gate struct iodev_snapshot *iodev = (struct iodev_snapshot *)v2; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate if (iodev == NULL) 347*7c478bd9Sstevel@tonic-gate return; 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate (void) printf("%c%c ", iodev->is_name[0], iodev->is_name[2]); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 353*7c478bd9Sstevel@tonic-gate static void 354*7c478bd9Sstevel@tonic-gate printhdr(int sig) 355*7c478bd9Sstevel@tonic-gate { 356*7c478bd9Sstevel@tonic-gate int i = df.if_max_iodevs - ss->s_nr_iodevs; 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate if (pflag) { 359*7c478bd9Sstevel@tonic-gate (void) printf(" memory page "); 360*7c478bd9Sstevel@tonic-gate (void) printf("executable anonymous filesystem \n"); 361*7c478bd9Sstevel@tonic-gate (void) printf(" swap free re mf fr de sr "); 362*7c478bd9Sstevel@tonic-gate (void) printf("epi epo epf api apo apf fpi fpo fpf\n"); 363*7c478bd9Sstevel@tonic-gate lines = REPRINT; 364*7c478bd9Sstevel@tonic-gate return; 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate (void) printf(" kthr memory page "); 368*7c478bd9Sstevel@tonic-gate (void) printf("disk faults cpu\n"); 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate if (swflag) 371*7c478bd9Sstevel@tonic-gate (void) printf(" r b w swap free si so pi po fr de sr "); 372*7c478bd9Sstevel@tonic-gate else 373*7c478bd9Sstevel@tonic-gate (void) printf(" r b w swap free re mf pi po fr de sr "); 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate (void) snapshot_walk(SNAP_IODEVS, NULL, ss, print_disk, NULL); 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate while (i-- > 0) 378*7c478bd9Sstevel@tonic-gate (void) printf("-- "); 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate (void) printf(" in sy cs us sy id\n"); 381*7c478bd9Sstevel@tonic-gate lines = REPRINT; 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate static void 385*7c478bd9Sstevel@tonic-gate sum_out(char const *pretty, kstat_t *ks, char *name) 386*7c478bd9Sstevel@tonic-gate { 387*7c478bd9Sstevel@tonic-gate kstat_named_t *ksn = kstat_data_lookup(ks, name); 388*7c478bd9Sstevel@tonic-gate if (ksn == NULL) { 389*7c478bd9Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', '%s') failed", 390*7c478bd9Sstevel@tonic-gate ks->ks_name, name); 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate (void) printf("%9llu %s\n", ksn->value.ui64, pretty); 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate static void 397*7c478bd9Sstevel@tonic-gate dosum(struct sys_snapshot *ss) 398*7c478bd9Sstevel@tonic-gate { 399*7c478bd9Sstevel@tonic-gate uint64_t total_faults; 400*7c478bd9Sstevel@tonic-gate kstat_named_t *ksn; 401*7c478bd9Sstevel@tonic-gate long double nchtotal; 402*7c478bd9Sstevel@tonic-gate uint64_t nchhits; 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate sum_out("swap ins", &ss->ss_agg_vm, "swapin"); 405*7c478bd9Sstevel@tonic-gate sum_out("swap outs", &ss->ss_agg_vm, "swapout"); 406*7c478bd9Sstevel@tonic-gate sum_out("pages swapped in", &ss->ss_agg_vm, "pgswapin"); 407*7c478bd9Sstevel@tonic-gate sum_out("pages swapped out", &ss->ss_agg_vm, "pgswapout"); 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate ksn = kstat_data_lookup(&ss->ss_agg_vm, "hat_fault"); 410*7c478bd9Sstevel@tonic-gate if (ksn == NULL) { 411*7c478bd9Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', 'hat_fault') failed", 412*7c478bd9Sstevel@tonic-gate ss->ss_agg_vm.ks_name); 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate total_faults = ksn->value.ui64; 415*7c478bd9Sstevel@tonic-gate ksn = kstat_data_lookup(&ss->ss_agg_vm, "as_fault"); 416*7c478bd9Sstevel@tonic-gate if (ksn == NULL) { 417*7c478bd9Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', 'as_fault') failed", 418*7c478bd9Sstevel@tonic-gate ss->ss_agg_vm.ks_name); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate total_faults += ksn->value.ui64; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate (void) printf("%9llu total address trans. faults taken\n", 423*7c478bd9Sstevel@tonic-gate total_faults); 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate sum_out("page ins", &ss->ss_agg_vm, "pgin"); 426*7c478bd9Sstevel@tonic-gate sum_out("page outs", &ss->ss_agg_vm, "pgout"); 427*7c478bd9Sstevel@tonic-gate sum_out("pages paged in", &ss->ss_agg_vm, "pgpgin"); 428*7c478bd9Sstevel@tonic-gate sum_out("pages paged out", &ss->ss_agg_vm, "pgpgout"); 429*7c478bd9Sstevel@tonic-gate sum_out("total reclaims", &ss->ss_agg_vm, "pgrec"); 430*7c478bd9Sstevel@tonic-gate sum_out("reclaims from free list", &ss->ss_agg_vm, "pgfrec"); 431*7c478bd9Sstevel@tonic-gate sum_out("micro (hat) faults", &ss->ss_agg_vm, "hat_fault"); 432*7c478bd9Sstevel@tonic-gate sum_out("minor (as) faults", &ss->ss_agg_vm, "as_fault"); 433*7c478bd9Sstevel@tonic-gate sum_out("major faults", &ss->ss_agg_vm, "maj_fault"); 434*7c478bd9Sstevel@tonic-gate sum_out("copy-on-write faults", &ss->ss_agg_vm, "cow_fault"); 435*7c478bd9Sstevel@tonic-gate sum_out("zero fill page faults", &ss->ss_agg_vm, "zfod"); 436*7c478bd9Sstevel@tonic-gate sum_out("pages examined by the clock daemon", &ss->ss_agg_vm, "scan"); 437*7c478bd9Sstevel@tonic-gate sum_out("revolutions of the clock hand", &ss->ss_agg_vm, "rev"); 438*7c478bd9Sstevel@tonic-gate sum_out("pages freed by the clock daemon", &ss->ss_agg_vm, "dfree"); 439*7c478bd9Sstevel@tonic-gate sum_out("forks", &ss->ss_agg_sys, "sysfork"); 440*7c478bd9Sstevel@tonic-gate sum_out("vforks", &ss->ss_agg_sys, "sysvfork"); 441*7c478bd9Sstevel@tonic-gate sum_out("execs", &ss->ss_agg_sys, "sysexec"); 442*7c478bd9Sstevel@tonic-gate sum_out("cpu context switches", &ss->ss_agg_sys, "pswitch"); 443*7c478bd9Sstevel@tonic-gate sum_out("device interrupts", &ss->ss_agg_sys, "intr"); 444*7c478bd9Sstevel@tonic-gate sum_out("traps", &ss->ss_agg_sys, "trap"); 445*7c478bd9Sstevel@tonic-gate sum_out("system calls", &ss->ss_agg_sys, "syscall"); 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate nchtotal = (long double) ss->ss_nc.ncs_hits.value.ui64 + 448*7c478bd9Sstevel@tonic-gate (long double) ss->ss_nc.ncs_misses.value.ui64; 449*7c478bd9Sstevel@tonic-gate nchhits = ss->ss_nc.ncs_hits.value.ui64; 450*7c478bd9Sstevel@tonic-gate (void) printf("%9.0Lf total name lookups (cache hits %.0Lf%%)\n", 451*7c478bd9Sstevel@tonic-gate nchtotal, nchhits / denom(nchtotal) * 100); 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate sum_out("user cpu", &ss->ss_agg_sys, "cpu_ticks_user"); 454*7c478bd9Sstevel@tonic-gate sum_out("system cpu", &ss->ss_agg_sys, "cpu_ticks_kernel"); 455*7c478bd9Sstevel@tonic-gate sum_out("idle cpu", &ss->ss_agg_sys, "cpu_ticks_idle"); 456*7c478bd9Sstevel@tonic-gate sum_out("wait cpu", &ss->ss_agg_sys, "cpu_ticks_wait"); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate static void 460*7c478bd9Sstevel@tonic-gate dointr(struct snapshot *ss) 461*7c478bd9Sstevel@tonic-gate { 462*7c478bd9Sstevel@tonic-gate size_t i; 463*7c478bd9Sstevel@tonic-gate ulong_t total = 0; 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate (void) printf("interrupt total rate\n"); 466*7c478bd9Sstevel@tonic-gate (void) printf("--------------------------------\n"); 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate for (i = 0; i < ss->s_nr_intrs; i++) { 469*7c478bd9Sstevel@tonic-gate (void) printf("%-12.8s %10lu %8.0f\n", 470*7c478bd9Sstevel@tonic-gate ss->s_intrs[i].is_name, ss->s_intrs[i].is_total, 471*7c478bd9Sstevel@tonic-gate ss->s_intrs[i].is_total / etime); 472*7c478bd9Sstevel@tonic-gate total += ss->s_intrs[i].is_total; 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate (void) printf("--------------------------------\n"); 476*7c478bd9Sstevel@tonic-gate (void) printf("Total %10lu %8.0f\n", total, total / etime); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate static void 480*7c478bd9Sstevel@tonic-gate docachestats(kstat_ctl_t *kc) 481*7c478bd9Sstevel@tonic-gate { 482*7c478bd9Sstevel@tonic-gate struct snapshot *old; 483*7c478bd9Sstevel@tonic-gate struct snapshot *new; 484*7c478bd9Sstevel@tonic-gate int i; 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate old = acquire_snapshot(kc, SNAP_FLUSHES, NULL); 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate if (iter == 0) { 489*7c478bd9Sstevel@tonic-gate (void) printf("flush statistics: (totals)\n"); 490*7c478bd9Sstevel@tonic-gate (void) printf("%8s%8s%8s%8s%8s%8s\n", 491*7c478bd9Sstevel@tonic-gate "usr", "ctx", "rgn", "seg", "pag", "par"); 492*7c478bd9Sstevel@tonic-gate (void) printf(" %7d %7d %7d %7d %7d %7d\n", 493*7c478bd9Sstevel@tonic-gate old->s_flushes.f_usr, old->s_flushes.f_ctx, 494*7c478bd9Sstevel@tonic-gate old->s_flushes.f_region, old->s_flushes.f_segment, 495*7c478bd9Sstevel@tonic-gate old->s_flushes.f_page, old->s_flushes.f_partial); 496*7c478bd9Sstevel@tonic-gate return; 497*7c478bd9Sstevel@tonic-gate } 498*7c478bd9Sstevel@tonic-gate 499*7c478bd9Sstevel@tonic-gate (void) printf("flush statistics: (interval based)\n"); 500*7c478bd9Sstevel@tonic-gate for (i = 0; i < iter; i++) { 501*7c478bd9Sstevel@tonic-gate if (i % REPRINT == 0) 502*7c478bd9Sstevel@tonic-gate (void) printf("%8s%8s%8s%8s%8s%8s\n", 503*7c478bd9Sstevel@tonic-gate "usr", "ctx", "rgn", "seg", "pag", "par"); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, poll_interval); 506*7c478bd9Sstevel@tonic-gate new = acquire_snapshot(kc, SNAP_FLUSHES, NULL); 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate (void) printf(" %7d %7d %7d %7d %7d %7d\n", 509*7c478bd9Sstevel@tonic-gate new->s_flushes.f_usr - old->s_flushes.f_usr, 510*7c478bd9Sstevel@tonic-gate new->s_flushes.f_ctx - old->s_flushes.f_ctx, 511*7c478bd9Sstevel@tonic-gate new->s_flushes.f_region - old->s_flushes.f_region, 512*7c478bd9Sstevel@tonic-gate new->s_flushes.f_segment - old->s_flushes.f_segment, 513*7c478bd9Sstevel@tonic-gate new->s_flushes.f_page - old->s_flushes.f_page, 514*7c478bd9Sstevel@tonic-gate new->s_flushes.f_partial- old->s_flushes.f_partial); 515*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 516*7c478bd9Sstevel@tonic-gate free_snapshot(old); 517*7c478bd9Sstevel@tonic-gate old = new; 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate static void 522*7c478bd9Sstevel@tonic-gate usage(void) 523*7c478bd9Sstevel@tonic-gate { 524*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 525*7c478bd9Sstevel@tonic-gate "Usage: vmstat [-cipqsS] [disk ...] [interval [count]]\n"); 526*7c478bd9Sstevel@tonic-gate exit(1); 527*7c478bd9Sstevel@tonic-gate } 528