10Sstevel@tonic-gate /* 29123Sjohn.levon@sun.com * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate /* 70Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 80Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 90Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 100Sstevel@tonic-gate */ 110Sstevel@tonic-gate 120Sstevel@tonic-gate /* from UCB 5.4 5/17/86 */ 130Sstevel@tonic-gate /* from SunOS 4.1, SID 1.31 */ 140Sstevel@tonic-gate 150Sstevel@tonic-gate #include <stdio.h> 160Sstevel@tonic-gate #include <stdlib.h> 170Sstevel@tonic-gate #include <stdarg.h> 180Sstevel@tonic-gate #include <ctype.h> 190Sstevel@tonic-gate #include <unistd.h> 200Sstevel@tonic-gate #include <memory.h> 210Sstevel@tonic-gate #include <string.h> 220Sstevel@tonic-gate #include <fcntl.h> 230Sstevel@tonic-gate #include <errno.h> 240Sstevel@tonic-gate #include <signal.h> 250Sstevel@tonic-gate #include <values.h> 260Sstevel@tonic-gate #include <poll.h> 279123Sjohn.levon@sun.com #include <locale.h> 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include "statcommon.h" 300Sstevel@tonic-gate 315461Stc35445 char *cmdname = "vmstat"; 325461Stc35445 int caught_cont = 0; 330Sstevel@tonic-gate 34*10265SKrishnendu.Sadhukhan@Sun.COM static uint_t timestamp_fmt = NODATE; 359123Sjohn.levon@sun.com 360Sstevel@tonic-gate static int hz; 370Sstevel@tonic-gate static int pagesize; 380Sstevel@tonic-gate static double etime; 390Sstevel@tonic-gate static int lines = 1; 400Sstevel@tonic-gate static int swflag = 0, cflag = 0, pflag = 0; 410Sstevel@tonic-gate static int suppress_state; 420Sstevel@tonic-gate static long iter = 0; 435461Stc35445 static hrtime_t period_n = 0; 440Sstevel@tonic-gate static struct snapshot *ss; 450Sstevel@tonic-gate 460Sstevel@tonic-gate struct iodev_filter df; 470Sstevel@tonic-gate 480Sstevel@tonic-gate #define pgtok(a) ((a) * (pagesize >> 10)) 490Sstevel@tonic-gate #define denom(x) ((x) ? (x) : 1) 500Sstevel@tonic-gate #define REPRINT 19 510Sstevel@tonic-gate 520Sstevel@tonic-gate static void dovmstats(struct snapshot *old, struct snapshot *new); 530Sstevel@tonic-gate static void printhdr(int); 540Sstevel@tonic-gate static void dosum(struct sys_snapshot *ss); 550Sstevel@tonic-gate static void dointr(struct snapshot *ss); 565461Stc35445 static void docachestats(kstat_ctl_t *kc, hrtime_t interval, int forever); 570Sstevel@tonic-gate static void usage(void); 580Sstevel@tonic-gate 590Sstevel@tonic-gate int 600Sstevel@tonic-gate main(int argc, char **argv) 610Sstevel@tonic-gate { 620Sstevel@tonic-gate struct snapshot *old = NULL; 630Sstevel@tonic-gate enum snapshot_types types = SNAP_SYSTEM; 640Sstevel@tonic-gate int summary = 0; 650Sstevel@tonic-gate int intr = 0; 660Sstevel@tonic-gate kstat_ctl_t *kc; 675461Stc35445 int forever = 0; 685461Stc35445 hrtime_t start_n; 699123Sjohn.levon@sun.com int c; 709123Sjohn.levon@sun.com 719123Sjohn.levon@sun.com (void) setlocale(LC_ALL, ""); 729123Sjohn.levon@sun.com #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 739123Sjohn.levon@sun.com #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 749123Sjohn.levon@sun.com #endif 759123Sjohn.levon@sun.com (void) textdomain(TEXT_DOMAIN); 760Sstevel@tonic-gate 770Sstevel@tonic-gate pagesize = sysconf(_SC_PAGESIZE); 780Sstevel@tonic-gate hz = sysconf(_SC_CLK_TCK); 790Sstevel@tonic-gate 809123Sjohn.levon@sun.com while ((c = getopt(argc, argv, "cipqsST:")) != EOF) 819123Sjohn.levon@sun.com switch (c) { 829123Sjohn.levon@sun.com case 'S': 839123Sjohn.levon@sun.com swflag = !swflag; 849123Sjohn.levon@sun.com break; 859123Sjohn.levon@sun.com case 's': 869123Sjohn.levon@sun.com summary = 1; 879123Sjohn.levon@sun.com break; 889123Sjohn.levon@sun.com case 'i': 899123Sjohn.levon@sun.com intr = 1; 909123Sjohn.levon@sun.com break; 919123Sjohn.levon@sun.com case 'c': 929123Sjohn.levon@sun.com cflag++; 939123Sjohn.levon@sun.com break; 949123Sjohn.levon@sun.com case 'q': 959123Sjohn.levon@sun.com suppress_state = 1; 969123Sjohn.levon@sun.com break; 979123Sjohn.levon@sun.com case 'p': 989123Sjohn.levon@sun.com pflag++; /* detailed paging info */ 999123Sjohn.levon@sun.com break; 1009123Sjohn.levon@sun.com case 'T': 1019123Sjohn.levon@sun.com if (optarg) { 1029123Sjohn.levon@sun.com if (*optarg == 'u') 1039123Sjohn.levon@sun.com timestamp_fmt = UDATE; 1049123Sjohn.levon@sun.com else if (*optarg == 'd') 1059123Sjohn.levon@sun.com timestamp_fmt = DDATE; 1069123Sjohn.levon@sun.com else 1079123Sjohn.levon@sun.com usage(); 1089123Sjohn.levon@sun.com } else { 1090Sstevel@tonic-gate usage(); 1100Sstevel@tonic-gate } 1119123Sjohn.levon@sun.com break; 1129123Sjohn.levon@sun.com default: 1139123Sjohn.levon@sun.com usage(); 1140Sstevel@tonic-gate } 1159123Sjohn.levon@sun.com 1169123Sjohn.levon@sun.com argc -= optind; 1179123Sjohn.levon@sun.com argv += optind; 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate /* consistency with iostat */ 1200Sstevel@tonic-gate types |= SNAP_CPUS; 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate if (intr) 1230Sstevel@tonic-gate types |= SNAP_INTERRUPTS; 1240Sstevel@tonic-gate if (cflag) 1250Sstevel@tonic-gate types |= SNAP_FLUSHES; 1260Sstevel@tonic-gate if (!intr) 1270Sstevel@tonic-gate types |= SNAP_IODEVS; 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate /* max to fit in less than 80 characters */ 1300Sstevel@tonic-gate df.if_max_iodevs = 4; 1310Sstevel@tonic-gate df.if_allowed_types = IODEV_DISK; 1320Sstevel@tonic-gate df.if_nr_names = 0; 1330Sstevel@tonic-gate df.if_names = safe_alloc(df.if_max_iodevs * sizeof (char *)); 1340Sstevel@tonic-gate (void) memset(df.if_names, 0, df.if_max_iodevs * sizeof (char *)); 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate while (argc > 0 && !isdigit(argv[0][0]) && 1379123Sjohn.levon@sun.com df.if_nr_names < df.if_max_iodevs) { 1380Sstevel@tonic-gate df.if_names[df.if_nr_names] = *argv; 1390Sstevel@tonic-gate df.if_nr_names++; 1400Sstevel@tonic-gate argc--, argv++; 1410Sstevel@tonic-gate } 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate kc = open_kstat(); 1440Sstevel@tonic-gate 1455461Stc35445 start_n = gethrtime(); 1465461Stc35445 1470Sstevel@tonic-gate ss = acquire_snapshot(kc, types, &df); 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate /* time, in seconds, since boot */ 1500Sstevel@tonic-gate etime = ss->s_sys.ss_ticks / hz; 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate if (intr) { 1530Sstevel@tonic-gate dointr(ss); 1540Sstevel@tonic-gate free_snapshot(ss); 1550Sstevel@tonic-gate exit(0); 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate if (summary) { 1580Sstevel@tonic-gate dosum(&ss->s_sys); 1590Sstevel@tonic-gate free_snapshot(ss); 1600Sstevel@tonic-gate exit(0); 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate if (argc > 0) { 1640Sstevel@tonic-gate long interval; 1650Sstevel@tonic-gate char *endptr; 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate errno = 0; 1680Sstevel@tonic-gate interval = strtol(argv[0], &endptr, 10); 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate if (errno > 0 || *endptr != '\0' || interval <= 0 || 1710Sstevel@tonic-gate interval > MAXINT) 1720Sstevel@tonic-gate usage(); 1735461Stc35445 period_n = (hrtime_t)interval * NANOSEC; 1745461Stc35445 if (period_n <= 0) 1750Sstevel@tonic-gate usage(); 1760Sstevel@tonic-gate iter = MAXLONG; 1770Sstevel@tonic-gate if (argc > 1) { 1780Sstevel@tonic-gate iter = strtol(argv[1], NULL, 10); 1790Sstevel@tonic-gate if (errno > 0 || *endptr != '\0' || iter <= 0) 1800Sstevel@tonic-gate usage(); 1815461Stc35445 } else 1825461Stc35445 forever = 1; 1830Sstevel@tonic-gate if (argc > 2) 1840Sstevel@tonic-gate usage(); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate if (cflag) { 1880Sstevel@tonic-gate free_snapshot(ss); 1895461Stc35445 docachestats(kc, period_n, forever); 1900Sstevel@tonic-gate exit(0); 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate (void) sigset(SIGCONT, printhdr); 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate dovmstats(old, ss); 1965461Stc35445 while (forever || --iter > 0) { 1975461Stc35445 /* (void) poll(NULL, 0, poll_interval); */ 1985461Stc35445 1995461Stc35445 /* Have a kip */ 2005461Stc35445 sleep_until(&start_n, period_n, forever, &caught_cont); 2015461Stc35445 2020Sstevel@tonic-gate free_snapshot(old); 2030Sstevel@tonic-gate old = ss; 2040Sstevel@tonic-gate ss = acquire_snapshot(kc, types, &df); 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate if (!suppress_state) 2070Sstevel@tonic-gate snapshot_report_changes(old, ss); 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate /* if config changed, show stats from boot */ 2100Sstevel@tonic-gate if (snapshot_has_changed(old, ss)) { 2110Sstevel@tonic-gate free_snapshot(old); 2120Sstevel@tonic-gate old = NULL; 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate dovmstats(old, ss); 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate free_snapshot(old); 2190Sstevel@tonic-gate free_snapshot(ss); 2200Sstevel@tonic-gate free(df.if_names); 2210Sstevel@tonic-gate (void) kstat_close(kc); 2220Sstevel@tonic-gate return (0); 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate #define DELTA(v) (new->v - (old ? old->v : 0)) 2260Sstevel@tonic-gate #define ADJ(n) ((adj <= 0) ? n : (adj >= n) ? 1 : n - adj) 2270Sstevel@tonic-gate #define adjprintf(fmt, n, val) adj -= (n + 1) - printf(fmt, ADJ(n), val) 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate static int adj; /* number of excess columns */ 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate /*ARGSUSED*/ 2320Sstevel@tonic-gate static void 2330Sstevel@tonic-gate show_disk(void *v1, void *v2, void *d) 2340Sstevel@tonic-gate { 2350Sstevel@tonic-gate struct iodev_snapshot *old = (struct iodev_snapshot *)v1; 2360Sstevel@tonic-gate struct iodev_snapshot *new = (struct iodev_snapshot *)v2; 2370Sstevel@tonic-gate hrtime_t oldtime = new->is_crtime; 2380Sstevel@tonic-gate double hr_etime; 2390Sstevel@tonic-gate double reads, writes; 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate if (new == NULL) 2420Sstevel@tonic-gate return; 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate if (old) 2450Sstevel@tonic-gate oldtime = old->is_stats.wlastupdate; 2460Sstevel@tonic-gate hr_etime = new->is_stats.wlastupdate - oldtime; 2470Sstevel@tonic-gate if (hr_etime == 0.0) 2480Sstevel@tonic-gate hr_etime = NANOSEC; 2490Sstevel@tonic-gate reads = new->is_stats.reads - (old ? old->is_stats.reads : 0); 2500Sstevel@tonic-gate writes = new->is_stats.writes - (old ? old->is_stats.writes : 0); 2510Sstevel@tonic-gate adjprintf(" %*.0f", 2, (reads + writes) / hr_etime * NANOSEC); 2520Sstevel@tonic-gate } 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate static void 2550Sstevel@tonic-gate dovmstats(struct snapshot *old, struct snapshot *new) 2560Sstevel@tonic-gate { 2570Sstevel@tonic-gate kstat_t *oldsys = NULL; 2580Sstevel@tonic-gate kstat_t *newsys = &new->s_sys.ss_agg_sys; 2590Sstevel@tonic-gate kstat_t *oldvm = NULL; 2600Sstevel@tonic-gate kstat_t *newvm = &new->s_sys.ss_agg_vm; 2610Sstevel@tonic-gate double percent_factor; 2620Sstevel@tonic-gate ulong_t updates; 2630Sstevel@tonic-gate int count; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate adj = 0; 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate if (old) { 2680Sstevel@tonic-gate oldsys = &old->s_sys.ss_agg_sys; 2690Sstevel@tonic-gate oldvm = &old->s_sys.ss_agg_vm; 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate etime = cpu_ticks_delta(oldsys, newsys); 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate percent_factor = 100.0 / denom(etime); 2750Sstevel@tonic-gate /* 2760Sstevel@tonic-gate * If any time has passed, convert etime to seconds per CPU 2770Sstevel@tonic-gate */ 2780Sstevel@tonic-gate etime = etime >= 1.0 ? (etime / nr_active_cpus(new)) / hz : 1.0; 2790Sstevel@tonic-gate updates = denom(DELTA(s_sys.ss_sysinfo.updates)); 2800Sstevel@tonic-gate 2819123Sjohn.levon@sun.com if (timestamp_fmt != NODATE) { 282*10265SKrishnendu.Sadhukhan@Sun.COM print_timestamp(timestamp_fmt); 2839123Sjohn.levon@sun.com lines--; 2849123Sjohn.levon@sun.com } 2859123Sjohn.levon@sun.com 2869123Sjohn.levon@sun.com if (--lines <= 0) 2870Sstevel@tonic-gate printhdr(0); 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate adj = 0; 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate if (pflag) { 2920Sstevel@tonic-gate adjprintf(" %*u", 6, 2930Sstevel@tonic-gate pgtok((int)(DELTA(s_sys.ss_vminfo.swap_avail) / updates))); 2940Sstevel@tonic-gate adjprintf(" %*u", 5, 2950Sstevel@tonic-gate pgtok((int)(DELTA(s_sys.ss_vminfo.freemem) / updates))); 2960Sstevel@tonic-gate adjprintf(" %*.0f", 3, kstat_delta(oldvm, newvm, "pgrec") 2970Sstevel@tonic-gate / etime); 2980Sstevel@tonic-gate adjprintf(" %*.0f", 3, (kstat_delta(oldvm, newvm, "hat_fault") + 2990Sstevel@tonic-gate kstat_delta(oldvm, newvm, "as_fault")) / etime); 3000Sstevel@tonic-gate adjprintf(" %*.0f", 3, pgtok(kstat_delta(oldvm, newvm, "dfree")) 3010Sstevel@tonic-gate / etime); 3020Sstevel@tonic-gate adjprintf(" %*ld", 3, pgtok(new->s_sys.ss_deficit)); 3030Sstevel@tonic-gate adjprintf(" %*.0f", 3, kstat_delta(oldvm, newvm, "scan") 3040Sstevel@tonic-gate / etime); 3050Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3060Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execpgin")) / etime); 3070Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3080Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execpgout")) / etime); 3090Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3100Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execfree")) / etime); 3110Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3120Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonpgin")) / etime); 3130Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3140Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonpgout")) / etime); 3150Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3160Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonfree")) / etime); 3170Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3180Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fspgin")) / etime); 3190Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3200Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fspgout")) / etime); 3210Sstevel@tonic-gate adjprintf(" %*.0f\n", 4, 3220Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fsfree")) / etime); 3230Sstevel@tonic-gate (void) fflush(stdout); 3240Sstevel@tonic-gate return; 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.runque) / updates); 3280Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.waiting) / updates); 3290Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.swpque) / updates); 3300Sstevel@tonic-gate adjprintf(" %*u", 6, pgtok((int)(DELTA(s_sys.ss_vminfo.swap_avail) 3310Sstevel@tonic-gate / updates))); 3320Sstevel@tonic-gate adjprintf(" %*u", 5, pgtok((int)(DELTA(s_sys.ss_vminfo.freemem) 3339123Sjohn.levon@sun.com / updates))); 3340Sstevel@tonic-gate adjprintf(" %*.0f", 3, swflag? 3350Sstevel@tonic-gate kstat_delta(oldvm, newvm, "swapin") / etime : 3360Sstevel@tonic-gate kstat_delta(oldvm, newvm, "pgrec") / etime); 3370Sstevel@tonic-gate adjprintf(" %*.0f", 3, swflag? 3380Sstevel@tonic-gate kstat_delta(oldvm, newvm, "swapout") / etime : 3390Sstevel@tonic-gate (kstat_delta(oldvm, newvm, "hat_fault") 3400Sstevel@tonic-gate + kstat_delta(oldvm, newvm, "as_fault")) 3410Sstevel@tonic-gate / etime); 3420Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "pgpgin")) 3430Sstevel@tonic-gate / etime); 3440Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "pgpgout")) 3450Sstevel@tonic-gate / etime); 3460Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "dfree")) 3470Sstevel@tonic-gate / etime); 3480Sstevel@tonic-gate adjprintf(" %*ld", 2, pgtok(new->s_sys.ss_deficit)); 3490Sstevel@tonic-gate adjprintf(" %*.0f", 2, kstat_delta(oldvm, newvm, "scan") / etime); 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate (void) snapshot_walk(SNAP_IODEVS, old, new, show_disk, NULL); 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate count = df.if_max_iodevs - new->s_nr_iodevs; 3540Sstevel@tonic-gate while (count-- > 0) 3550Sstevel@tonic-gate adjprintf(" %*d", 2, 0); 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "intr") / etime); 3580Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "syscall") / etime); 3590Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "pswitch") / etime); 3600Sstevel@tonic-gate adjprintf(" %*.0f", 2, 3610Sstevel@tonic-gate kstat_delta(oldsys, newsys, "cpu_ticks_user") * percent_factor); 3620Sstevel@tonic-gate adjprintf(" %*.0f", 2, kstat_delta(oldsys, newsys, "cpu_ticks_kernel") 3630Sstevel@tonic-gate * percent_factor); 3640Sstevel@tonic-gate adjprintf(" %*.0f\n", 2, (kstat_delta(oldsys, newsys, "cpu_ticks_idle") 3650Sstevel@tonic-gate + kstat_delta(oldsys, newsys, "cpu_ticks_wait")) 3660Sstevel@tonic-gate * percent_factor); 3670Sstevel@tonic-gate (void) fflush(stdout); 3680Sstevel@tonic-gate } 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate /*ARGSUSED*/ 3710Sstevel@tonic-gate static void 3720Sstevel@tonic-gate print_disk(void *v, void *v2, void *d) 3730Sstevel@tonic-gate { 3740Sstevel@tonic-gate struct iodev_snapshot *iodev = (struct iodev_snapshot *)v2; 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate if (iodev == NULL) 3770Sstevel@tonic-gate return; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate (void) printf("%c%c ", iodev->is_name[0], iodev->is_name[2]); 3800Sstevel@tonic-gate } 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate /* ARGSUSED */ 3830Sstevel@tonic-gate static void 3840Sstevel@tonic-gate printhdr(int sig) 3850Sstevel@tonic-gate { 3860Sstevel@tonic-gate int i = df.if_max_iodevs - ss->s_nr_iodevs; 3870Sstevel@tonic-gate 3885461Stc35445 if (sig == SIGCONT) 3895461Stc35445 caught_cont = 1; 3905461Stc35445 3910Sstevel@tonic-gate if (pflag) { 3920Sstevel@tonic-gate (void) printf(" memory page "); 3930Sstevel@tonic-gate (void) printf("executable anonymous filesystem \n"); 3940Sstevel@tonic-gate (void) printf(" swap free re mf fr de sr "); 3950Sstevel@tonic-gate (void) printf("epi epo epf api apo apf fpi fpo fpf\n"); 3960Sstevel@tonic-gate lines = REPRINT; 3970Sstevel@tonic-gate return; 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate (void) printf(" kthr memory page "); 4010Sstevel@tonic-gate (void) printf("disk faults cpu\n"); 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate if (swflag) 4040Sstevel@tonic-gate (void) printf(" r b w swap free si so pi po fr de sr "); 4050Sstevel@tonic-gate else 4060Sstevel@tonic-gate (void) printf(" r b w swap free re mf pi po fr de sr "); 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate (void) snapshot_walk(SNAP_IODEVS, NULL, ss, print_disk, NULL); 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate while (i-- > 0) 4110Sstevel@tonic-gate (void) printf("-- "); 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate (void) printf(" in sy cs us sy id\n"); 4140Sstevel@tonic-gate lines = REPRINT; 4150Sstevel@tonic-gate } 4160Sstevel@tonic-gate 4170Sstevel@tonic-gate static void 4180Sstevel@tonic-gate sum_out(char const *pretty, kstat_t *ks, char *name) 4190Sstevel@tonic-gate { 4200Sstevel@tonic-gate kstat_named_t *ksn = kstat_data_lookup(ks, name); 4210Sstevel@tonic-gate if (ksn == NULL) { 4220Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', '%s') failed", 4239123Sjohn.levon@sun.com ks->ks_name, name); 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate (void) printf("%9llu %s\n", ksn->value.ui64, pretty); 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate static void 4300Sstevel@tonic-gate dosum(struct sys_snapshot *ss) 4310Sstevel@tonic-gate { 4320Sstevel@tonic-gate uint64_t total_faults; 4330Sstevel@tonic-gate kstat_named_t *ksn; 4340Sstevel@tonic-gate long double nchtotal; 4350Sstevel@tonic-gate uint64_t nchhits; 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate sum_out("swap ins", &ss->ss_agg_vm, "swapin"); 4380Sstevel@tonic-gate sum_out("swap outs", &ss->ss_agg_vm, "swapout"); 4390Sstevel@tonic-gate sum_out("pages swapped in", &ss->ss_agg_vm, "pgswapin"); 4400Sstevel@tonic-gate sum_out("pages swapped out", &ss->ss_agg_vm, "pgswapout"); 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate ksn = kstat_data_lookup(&ss->ss_agg_vm, "hat_fault"); 4430Sstevel@tonic-gate if (ksn == NULL) { 4440Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', 'hat_fault') failed", 4459123Sjohn.levon@sun.com ss->ss_agg_vm.ks_name); 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate total_faults = ksn->value.ui64; 4480Sstevel@tonic-gate ksn = kstat_data_lookup(&ss->ss_agg_vm, "as_fault"); 4490Sstevel@tonic-gate if (ksn == NULL) { 4500Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', 'as_fault') failed", 4519123Sjohn.levon@sun.com ss->ss_agg_vm.ks_name); 4520Sstevel@tonic-gate } 4530Sstevel@tonic-gate total_faults += ksn->value.ui64; 4540Sstevel@tonic-gate 4550Sstevel@tonic-gate (void) printf("%9llu total address trans. faults taken\n", 4569123Sjohn.levon@sun.com total_faults); 4570Sstevel@tonic-gate 4580Sstevel@tonic-gate sum_out("page ins", &ss->ss_agg_vm, "pgin"); 4590Sstevel@tonic-gate sum_out("page outs", &ss->ss_agg_vm, "pgout"); 4600Sstevel@tonic-gate sum_out("pages paged in", &ss->ss_agg_vm, "pgpgin"); 4610Sstevel@tonic-gate sum_out("pages paged out", &ss->ss_agg_vm, "pgpgout"); 4620Sstevel@tonic-gate sum_out("total reclaims", &ss->ss_agg_vm, "pgrec"); 4630Sstevel@tonic-gate sum_out("reclaims from free list", &ss->ss_agg_vm, "pgfrec"); 4640Sstevel@tonic-gate sum_out("micro (hat) faults", &ss->ss_agg_vm, "hat_fault"); 4650Sstevel@tonic-gate sum_out("minor (as) faults", &ss->ss_agg_vm, "as_fault"); 4660Sstevel@tonic-gate sum_out("major faults", &ss->ss_agg_vm, "maj_fault"); 4670Sstevel@tonic-gate sum_out("copy-on-write faults", &ss->ss_agg_vm, "cow_fault"); 4680Sstevel@tonic-gate sum_out("zero fill page faults", &ss->ss_agg_vm, "zfod"); 4690Sstevel@tonic-gate sum_out("pages examined by the clock daemon", &ss->ss_agg_vm, "scan"); 4700Sstevel@tonic-gate sum_out("revolutions of the clock hand", &ss->ss_agg_vm, "rev"); 4710Sstevel@tonic-gate sum_out("pages freed by the clock daemon", &ss->ss_agg_vm, "dfree"); 4720Sstevel@tonic-gate sum_out("forks", &ss->ss_agg_sys, "sysfork"); 4730Sstevel@tonic-gate sum_out("vforks", &ss->ss_agg_sys, "sysvfork"); 4740Sstevel@tonic-gate sum_out("execs", &ss->ss_agg_sys, "sysexec"); 4750Sstevel@tonic-gate sum_out("cpu context switches", &ss->ss_agg_sys, "pswitch"); 4760Sstevel@tonic-gate sum_out("device interrupts", &ss->ss_agg_sys, "intr"); 4770Sstevel@tonic-gate sum_out("traps", &ss->ss_agg_sys, "trap"); 4780Sstevel@tonic-gate sum_out("system calls", &ss->ss_agg_sys, "syscall"); 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate nchtotal = (long double) ss->ss_nc.ncs_hits.value.ui64 + 4810Sstevel@tonic-gate (long double) ss->ss_nc.ncs_misses.value.ui64; 4820Sstevel@tonic-gate nchhits = ss->ss_nc.ncs_hits.value.ui64; 4830Sstevel@tonic-gate (void) printf("%9.0Lf total name lookups (cache hits %.0Lf%%)\n", 4840Sstevel@tonic-gate nchtotal, nchhits / denom(nchtotal) * 100); 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate sum_out("user cpu", &ss->ss_agg_sys, "cpu_ticks_user"); 4870Sstevel@tonic-gate sum_out("system cpu", &ss->ss_agg_sys, "cpu_ticks_kernel"); 4880Sstevel@tonic-gate sum_out("idle cpu", &ss->ss_agg_sys, "cpu_ticks_idle"); 4890Sstevel@tonic-gate sum_out("wait cpu", &ss->ss_agg_sys, "cpu_ticks_wait"); 4900Sstevel@tonic-gate } 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate static void 4930Sstevel@tonic-gate dointr(struct snapshot *ss) 4940Sstevel@tonic-gate { 4950Sstevel@tonic-gate size_t i; 4960Sstevel@tonic-gate ulong_t total = 0; 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate (void) printf("interrupt total rate\n"); 4990Sstevel@tonic-gate (void) printf("--------------------------------\n"); 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate for (i = 0; i < ss->s_nr_intrs; i++) { 5020Sstevel@tonic-gate (void) printf("%-12.8s %10lu %8.0f\n", 5039123Sjohn.levon@sun.com ss->s_intrs[i].is_name, ss->s_intrs[i].is_total, 5049123Sjohn.levon@sun.com ss->s_intrs[i].is_total / etime); 5050Sstevel@tonic-gate total += ss->s_intrs[i].is_total; 5060Sstevel@tonic-gate } 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate (void) printf("--------------------------------\n"); 5090Sstevel@tonic-gate (void) printf("Total %10lu %8.0f\n", total, total / etime); 5100Sstevel@tonic-gate } 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate static void 5135461Stc35445 docachestats(kstat_ctl_t *kc, hrtime_t interval, int forever) 5140Sstevel@tonic-gate { 5150Sstevel@tonic-gate struct snapshot *old; 5160Sstevel@tonic-gate struct snapshot *new; 5170Sstevel@tonic-gate int i; 5185461Stc35445 hrtime_t start; 5190Sstevel@tonic-gate 5205461Stc35445 start = gethrtime(); 5210Sstevel@tonic-gate old = acquire_snapshot(kc, SNAP_FLUSHES, NULL); 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate if (iter == 0) { 5240Sstevel@tonic-gate (void) printf("flush statistics: (totals)\n"); 5250Sstevel@tonic-gate (void) printf("%8s%8s%8s%8s%8s%8s\n", 5269123Sjohn.levon@sun.com "usr", "ctx", "rgn", "seg", "pag", "par"); 5270Sstevel@tonic-gate (void) printf(" %7d %7d %7d %7d %7d %7d\n", 5289123Sjohn.levon@sun.com old->s_flushes.f_usr, old->s_flushes.f_ctx, 5299123Sjohn.levon@sun.com old->s_flushes.f_region, old->s_flushes.f_segment, 5309123Sjohn.levon@sun.com old->s_flushes.f_page, old->s_flushes.f_partial); 5310Sstevel@tonic-gate return; 5320Sstevel@tonic-gate } 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate (void) printf("flush statistics: (interval based)\n"); 5350Sstevel@tonic-gate for (i = 0; i < iter; i++) { 5360Sstevel@tonic-gate if (i % REPRINT == 0) 5370Sstevel@tonic-gate (void) printf("%8s%8s%8s%8s%8s%8s\n", 5380Sstevel@tonic-gate "usr", "ctx", "rgn", "seg", "pag", "par"); 5390Sstevel@tonic-gate 5405461Stc35445 /* Have a kip */ 5415461Stc35445 sleep_until(&start, interval, forever, &caught_cont); 5425461Stc35445 5430Sstevel@tonic-gate new = acquire_snapshot(kc, SNAP_FLUSHES, NULL); 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate (void) printf(" %7d %7d %7d %7d %7d %7d\n", 5469123Sjohn.levon@sun.com new->s_flushes.f_usr - old->s_flushes.f_usr, 5479123Sjohn.levon@sun.com new->s_flushes.f_ctx - old->s_flushes.f_ctx, 5489123Sjohn.levon@sun.com new->s_flushes.f_region - old->s_flushes.f_region, 5499123Sjohn.levon@sun.com new->s_flushes.f_segment - old->s_flushes.f_segment, 5509123Sjohn.levon@sun.com new->s_flushes.f_page - old->s_flushes.f_page, 5519123Sjohn.levon@sun.com new->s_flushes.f_partial- old->s_flushes.f_partial); 5520Sstevel@tonic-gate (void) fflush(stdout); 5530Sstevel@tonic-gate free_snapshot(old); 5540Sstevel@tonic-gate old = new; 5550Sstevel@tonic-gate } 5560Sstevel@tonic-gate } 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate static void 5590Sstevel@tonic-gate usage(void) 5600Sstevel@tonic-gate { 5610Sstevel@tonic-gate (void) fprintf(stderr, 5629123Sjohn.levon@sun.com "Usage: vmstat [-cipqsS] [-T d|u] [disk ...] " 5639123Sjohn.levon@sun.com "[interval [count]]\n"); 5640Sstevel@tonic-gate exit(1); 5650Sstevel@tonic-gate } 566