17c478bd9Sstevel@tonic-gate /* 24944376cSJohn Levon * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 87c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 97c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate /* from UCB 5.4 5/17/86 */ 137c478bd9Sstevel@tonic-gate /* from SunOS 4.1, SID 1.31 */ 147c478bd9Sstevel@tonic-gate 157c478bd9Sstevel@tonic-gate #include <stdio.h> 167c478bd9Sstevel@tonic-gate #include <stdlib.h> 177c478bd9Sstevel@tonic-gate #include <stdarg.h> 187c478bd9Sstevel@tonic-gate #include <ctype.h> 197c478bd9Sstevel@tonic-gate #include <unistd.h> 207c478bd9Sstevel@tonic-gate #include <memory.h> 217c478bd9Sstevel@tonic-gate #include <string.h> 227c478bd9Sstevel@tonic-gate #include <fcntl.h> 237c478bd9Sstevel@tonic-gate #include <errno.h> 247c478bd9Sstevel@tonic-gate #include <signal.h> 257c478bd9Sstevel@tonic-gate #include <values.h> 267c478bd9Sstevel@tonic-gate #include <poll.h> 274944376cSJohn Levon #include <locale.h> 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include "statcommon.h" 307c478bd9Sstevel@tonic-gate 3100c76d6fStc35445 char *cmdname = "vmstat"; 3200c76d6fStc35445 int caught_cont = 0; 337c478bd9Sstevel@tonic-gate 34*26fd7700SKrishnendu Sadhukhan - Sun Microsystems static uint_t timestamp_fmt = NODATE; 354944376cSJohn Levon 367c478bd9Sstevel@tonic-gate static int hz; 377c478bd9Sstevel@tonic-gate static int pagesize; 387c478bd9Sstevel@tonic-gate static double etime; 397c478bd9Sstevel@tonic-gate static int lines = 1; 407c478bd9Sstevel@tonic-gate static int swflag = 0, cflag = 0, pflag = 0; 417c478bd9Sstevel@tonic-gate static int suppress_state; 427c478bd9Sstevel@tonic-gate static long iter = 0; 4300c76d6fStc35445 static hrtime_t period_n = 0; 447c478bd9Sstevel@tonic-gate static struct snapshot *ss; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate struct iodev_filter df; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #define pgtok(a) ((a) * (pagesize >> 10)) 497c478bd9Sstevel@tonic-gate #define denom(x) ((x) ? (x) : 1) 507c478bd9Sstevel@tonic-gate #define REPRINT 19 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate static void dovmstats(struct snapshot *old, struct snapshot *new); 537c478bd9Sstevel@tonic-gate static void printhdr(int); 547c478bd9Sstevel@tonic-gate static void dosum(struct sys_snapshot *ss); 557c478bd9Sstevel@tonic-gate static void dointr(struct snapshot *ss); 5600c76d6fStc35445 static void docachestats(kstat_ctl_t *kc, hrtime_t interval, int forever); 577c478bd9Sstevel@tonic-gate static void usage(void); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate int 607c478bd9Sstevel@tonic-gate main(int argc, char **argv) 617c478bd9Sstevel@tonic-gate { 627c478bd9Sstevel@tonic-gate struct snapshot *old = NULL; 637c478bd9Sstevel@tonic-gate enum snapshot_types types = SNAP_SYSTEM; 647c478bd9Sstevel@tonic-gate int summary = 0; 657c478bd9Sstevel@tonic-gate int intr = 0; 667c478bd9Sstevel@tonic-gate kstat_ctl_t *kc; 6700c76d6fStc35445 int forever = 0; 6800c76d6fStc35445 hrtime_t start_n; 694944376cSJohn Levon int c; 704944376cSJohn Levon 714944376cSJohn Levon (void) setlocale(LC_ALL, ""); 724944376cSJohn Levon #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 734944376cSJohn Levon #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 744944376cSJohn Levon #endif 754944376cSJohn Levon (void) textdomain(TEXT_DOMAIN); 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate pagesize = sysconf(_SC_PAGESIZE); 787c478bd9Sstevel@tonic-gate hz = sysconf(_SC_CLK_TCK); 797c478bd9Sstevel@tonic-gate 804944376cSJohn Levon while ((c = getopt(argc, argv, "cipqsST:")) != EOF) 814944376cSJohn Levon switch (c) { 827c478bd9Sstevel@tonic-gate case 'S': 837c478bd9Sstevel@tonic-gate swflag = !swflag; 847c478bd9Sstevel@tonic-gate break; 857c478bd9Sstevel@tonic-gate case 's': 867c478bd9Sstevel@tonic-gate summary = 1; 877c478bd9Sstevel@tonic-gate break; 887c478bd9Sstevel@tonic-gate case 'i': 897c478bd9Sstevel@tonic-gate intr = 1; 907c478bd9Sstevel@tonic-gate break; 917c478bd9Sstevel@tonic-gate case 'c': 927c478bd9Sstevel@tonic-gate cflag++; 937c478bd9Sstevel@tonic-gate break; 947c478bd9Sstevel@tonic-gate case 'q': 957c478bd9Sstevel@tonic-gate suppress_state = 1; 967c478bd9Sstevel@tonic-gate break; 977c478bd9Sstevel@tonic-gate case 'p': 987c478bd9Sstevel@tonic-gate pflag++; /* detailed paging info */ 997c478bd9Sstevel@tonic-gate break; 1004944376cSJohn Levon case 'T': 1014944376cSJohn Levon if (optarg) { 1024944376cSJohn Levon if (*optarg == 'u') 1034944376cSJohn Levon timestamp_fmt = UDATE; 1044944376cSJohn Levon else if (*optarg == 'd') 1054944376cSJohn Levon timestamp_fmt = DDATE; 1064944376cSJohn Levon else 1074944376cSJohn Levon usage(); 1084944376cSJohn Levon } else { 1094944376cSJohn Levon usage(); 1104944376cSJohn Levon } 1114944376cSJohn Levon break; 1127c478bd9Sstevel@tonic-gate default: 1137c478bd9Sstevel@tonic-gate usage(); 1147c478bd9Sstevel@tonic-gate } 1154944376cSJohn Levon 1164944376cSJohn Levon argc -= optind; 1174944376cSJohn Levon argv += optind; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate /* consistency with iostat */ 1207c478bd9Sstevel@tonic-gate types |= SNAP_CPUS; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate if (intr) 1237c478bd9Sstevel@tonic-gate types |= SNAP_INTERRUPTS; 1247c478bd9Sstevel@tonic-gate if (cflag) 1257c478bd9Sstevel@tonic-gate types |= SNAP_FLUSHES; 1267c478bd9Sstevel@tonic-gate if (!intr) 1277c478bd9Sstevel@tonic-gate types |= SNAP_IODEVS; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* max to fit in less than 80 characters */ 1307c478bd9Sstevel@tonic-gate df.if_max_iodevs = 4; 1317c478bd9Sstevel@tonic-gate df.if_allowed_types = IODEV_DISK; 1327c478bd9Sstevel@tonic-gate df.if_nr_names = 0; 1337c478bd9Sstevel@tonic-gate df.if_names = safe_alloc(df.if_max_iodevs * sizeof (char *)); 1347c478bd9Sstevel@tonic-gate (void) memset(df.if_names, 0, df.if_max_iodevs * sizeof (char *)); 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate while (argc > 0 && !isdigit(argv[0][0]) && 1377c478bd9Sstevel@tonic-gate df.if_nr_names < df.if_max_iodevs) { 1387c478bd9Sstevel@tonic-gate df.if_names[df.if_nr_names] = *argv; 1397c478bd9Sstevel@tonic-gate df.if_nr_names++; 1407c478bd9Sstevel@tonic-gate argc--, argv++; 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate kc = open_kstat(); 1447c478bd9Sstevel@tonic-gate 14500c76d6fStc35445 start_n = gethrtime(); 14600c76d6fStc35445 1477c478bd9Sstevel@tonic-gate ss = acquire_snapshot(kc, types, &df); 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* time, in seconds, since boot */ 1507c478bd9Sstevel@tonic-gate etime = ss->s_sys.ss_ticks / hz; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate if (intr) { 1537c478bd9Sstevel@tonic-gate dointr(ss); 1547c478bd9Sstevel@tonic-gate free_snapshot(ss); 1557c478bd9Sstevel@tonic-gate exit(0); 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate if (summary) { 1587c478bd9Sstevel@tonic-gate dosum(&ss->s_sys); 1597c478bd9Sstevel@tonic-gate free_snapshot(ss); 1607c478bd9Sstevel@tonic-gate exit(0); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate if (argc > 0) { 1647c478bd9Sstevel@tonic-gate long interval; 1657c478bd9Sstevel@tonic-gate char *endptr; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate errno = 0; 1687c478bd9Sstevel@tonic-gate interval = strtol(argv[0], &endptr, 10); 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate if (errno > 0 || *endptr != '\0' || interval <= 0 || 1717c478bd9Sstevel@tonic-gate interval > MAXINT) 1727c478bd9Sstevel@tonic-gate usage(); 17300c76d6fStc35445 period_n = (hrtime_t)interval * NANOSEC; 17400c76d6fStc35445 if (period_n <= 0) 1757c478bd9Sstevel@tonic-gate usage(); 1767c478bd9Sstevel@tonic-gate iter = MAXLONG; 1777c478bd9Sstevel@tonic-gate if (argc > 1) { 1787c478bd9Sstevel@tonic-gate iter = strtol(argv[1], NULL, 10); 1797c478bd9Sstevel@tonic-gate if (errno > 0 || *endptr != '\0' || iter <= 0) 1807c478bd9Sstevel@tonic-gate usage(); 18100c76d6fStc35445 } else 18200c76d6fStc35445 forever = 1; 1837c478bd9Sstevel@tonic-gate if (argc > 2) 1847c478bd9Sstevel@tonic-gate usage(); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if (cflag) { 1887c478bd9Sstevel@tonic-gate free_snapshot(ss); 18900c76d6fStc35445 docachestats(kc, period_n, forever); 1907c478bd9Sstevel@tonic-gate exit(0); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate (void) sigset(SIGCONT, printhdr); 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate dovmstats(old, ss); 19600c76d6fStc35445 while (forever || --iter > 0) { 19700c76d6fStc35445 /* (void) poll(NULL, 0, poll_interval); */ 19800c76d6fStc35445 19900c76d6fStc35445 /* Have a kip */ 20000c76d6fStc35445 sleep_until(&start_n, period_n, forever, &caught_cont); 20100c76d6fStc35445 2027c478bd9Sstevel@tonic-gate free_snapshot(old); 2037c478bd9Sstevel@tonic-gate old = ss; 2047c478bd9Sstevel@tonic-gate ss = acquire_snapshot(kc, types, &df); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate if (!suppress_state) 2077c478bd9Sstevel@tonic-gate snapshot_report_changes(old, ss); 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* if config changed, show stats from boot */ 2107c478bd9Sstevel@tonic-gate if (snapshot_has_changed(old, ss)) { 2117c478bd9Sstevel@tonic-gate free_snapshot(old); 2127c478bd9Sstevel@tonic-gate old = NULL; 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate dovmstats(old, ss); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate free_snapshot(old); 2197c478bd9Sstevel@tonic-gate free_snapshot(ss); 2207c478bd9Sstevel@tonic-gate free(df.if_names); 2217c478bd9Sstevel@tonic-gate (void) kstat_close(kc); 2227c478bd9Sstevel@tonic-gate return (0); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate #define DELTA(v) (new->v - (old ? old->v : 0)) 2267c478bd9Sstevel@tonic-gate #define ADJ(n) ((adj <= 0) ? n : (adj >= n) ? 1 : n - adj) 2277c478bd9Sstevel@tonic-gate #define adjprintf(fmt, n, val) adj -= (n + 1) - printf(fmt, ADJ(n), val) 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate static int adj; /* number of excess columns */ 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2327c478bd9Sstevel@tonic-gate static void 2337c478bd9Sstevel@tonic-gate show_disk(void *v1, void *v2, void *d) 2347c478bd9Sstevel@tonic-gate { 2357c478bd9Sstevel@tonic-gate struct iodev_snapshot *old = (struct iodev_snapshot *)v1; 2367c478bd9Sstevel@tonic-gate struct iodev_snapshot *new = (struct iodev_snapshot *)v2; 2377c478bd9Sstevel@tonic-gate hrtime_t oldtime = new->is_crtime; 2387c478bd9Sstevel@tonic-gate double hr_etime; 2397c478bd9Sstevel@tonic-gate double reads, writes; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if (new == NULL) 2427c478bd9Sstevel@tonic-gate return; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate if (old) 2457c478bd9Sstevel@tonic-gate oldtime = old->is_stats.wlastupdate; 2467c478bd9Sstevel@tonic-gate hr_etime = new->is_stats.wlastupdate - oldtime; 2477c478bd9Sstevel@tonic-gate if (hr_etime == 0.0) 2487c478bd9Sstevel@tonic-gate hr_etime = NANOSEC; 2497c478bd9Sstevel@tonic-gate reads = new->is_stats.reads - (old ? old->is_stats.reads : 0); 2507c478bd9Sstevel@tonic-gate writes = new->is_stats.writes - (old ? old->is_stats.writes : 0); 2517c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, (reads + writes) / hr_etime * NANOSEC); 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate static void 2557c478bd9Sstevel@tonic-gate dovmstats(struct snapshot *old, struct snapshot *new) 2567c478bd9Sstevel@tonic-gate { 2577c478bd9Sstevel@tonic-gate kstat_t *oldsys = NULL; 2587c478bd9Sstevel@tonic-gate kstat_t *newsys = &new->s_sys.ss_agg_sys; 2597c478bd9Sstevel@tonic-gate kstat_t *oldvm = NULL; 2607c478bd9Sstevel@tonic-gate kstat_t *newvm = &new->s_sys.ss_agg_vm; 2617c478bd9Sstevel@tonic-gate double percent_factor; 2627c478bd9Sstevel@tonic-gate ulong_t updates; 2637c478bd9Sstevel@tonic-gate int count; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate adj = 0; 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate if (old) { 2687c478bd9Sstevel@tonic-gate oldsys = &old->s_sys.ss_agg_sys; 2697c478bd9Sstevel@tonic-gate oldvm = &old->s_sys.ss_agg_vm; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate etime = cpu_ticks_delta(oldsys, newsys); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate percent_factor = 100.0 / denom(etime); 2757c478bd9Sstevel@tonic-gate /* 2767c478bd9Sstevel@tonic-gate * If any time has passed, convert etime to seconds per CPU 2777c478bd9Sstevel@tonic-gate */ 2787c478bd9Sstevel@tonic-gate etime = etime >= 1.0 ? (etime / nr_active_cpus(new)) / hz : 1.0; 2797c478bd9Sstevel@tonic-gate updates = denom(DELTA(s_sys.ss_sysinfo.updates)); 2807c478bd9Sstevel@tonic-gate 2814944376cSJohn Levon if (timestamp_fmt != NODATE) { 282*26fd7700SKrishnendu Sadhukhan - Sun Microsystems print_timestamp(timestamp_fmt); 2834944376cSJohn Levon lines--; 2844944376cSJohn Levon } 2854944376cSJohn Levon 2864944376cSJohn Levon if (--lines <= 0) 2877c478bd9Sstevel@tonic-gate printhdr(0); 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate adj = 0; 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate if (pflag) { 2927c478bd9Sstevel@tonic-gate adjprintf(" %*u", 6, 2937c478bd9Sstevel@tonic-gate pgtok((int)(DELTA(s_sys.ss_vminfo.swap_avail) / updates))); 2947c478bd9Sstevel@tonic-gate adjprintf(" %*u", 5, 2957c478bd9Sstevel@tonic-gate pgtok((int)(DELTA(s_sys.ss_vminfo.freemem) / updates))); 2967c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, kstat_delta(oldvm, newvm, "pgrec") 2977c478bd9Sstevel@tonic-gate / etime); 2987c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, (kstat_delta(oldvm, newvm, "hat_fault") + 2997c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "as_fault")) / etime); 3007c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, pgtok(kstat_delta(oldvm, newvm, "dfree")) 3017c478bd9Sstevel@tonic-gate / etime); 3027c478bd9Sstevel@tonic-gate adjprintf(" %*ld", 3, pgtok(new->s_sys.ss_deficit)); 3037c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, kstat_delta(oldvm, newvm, "scan") 3047c478bd9Sstevel@tonic-gate / etime); 3057c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3067c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execpgin")) / etime); 3077c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3087c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execpgout")) / etime); 3097c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3107c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "execfree")) / etime); 3117c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3127c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonpgin")) / etime); 3137c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3147c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonpgout")) / etime); 3157c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3167c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "anonfree")) / etime); 3177c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3187c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fspgin")) / etime); 3197c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, 3207c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fspgout")) / etime); 3217c478bd9Sstevel@tonic-gate adjprintf(" %*.0f\n", 4, 3227c478bd9Sstevel@tonic-gate pgtok(kstat_delta(oldvm, newvm, "fsfree")) / etime); 3237c478bd9Sstevel@tonic-gate (void) fflush(stdout); 3247c478bd9Sstevel@tonic-gate return; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.runque) / updates); 3287c478bd9Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.waiting) / updates); 3297c478bd9Sstevel@tonic-gate adjprintf(" %*lu", 1, DELTA(s_sys.ss_sysinfo.swpque) / updates); 3307c478bd9Sstevel@tonic-gate adjprintf(" %*u", 6, pgtok((int)(DELTA(s_sys.ss_vminfo.swap_avail) 3317c478bd9Sstevel@tonic-gate / updates))); 3327c478bd9Sstevel@tonic-gate adjprintf(" %*u", 5, pgtok((int)(DELTA(s_sys.ss_vminfo.freemem) 3337c478bd9Sstevel@tonic-gate / updates))); 3347c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, swflag? 3357c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "swapin") / etime : 3367c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "pgrec") / etime); 3377c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 3, swflag? 3387c478bd9Sstevel@tonic-gate kstat_delta(oldvm, newvm, "swapout") / etime : 3397c478bd9Sstevel@tonic-gate (kstat_delta(oldvm, newvm, "hat_fault") 3407c478bd9Sstevel@tonic-gate + kstat_delta(oldvm, newvm, "as_fault")) 3417c478bd9Sstevel@tonic-gate / etime); 3427c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "pgpgin")) 3437c478bd9Sstevel@tonic-gate / etime); 3447c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "pgpgout")) 3457c478bd9Sstevel@tonic-gate / etime); 3467c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, pgtok(kstat_delta(oldvm, newvm, "dfree")) 3477c478bd9Sstevel@tonic-gate / etime); 3487c478bd9Sstevel@tonic-gate adjprintf(" %*ld", 2, pgtok(new->s_sys.ss_deficit)); 3497c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, kstat_delta(oldvm, newvm, "scan") / etime); 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate (void) snapshot_walk(SNAP_IODEVS, old, new, show_disk, NULL); 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate count = df.if_max_iodevs - new->s_nr_iodevs; 3547c478bd9Sstevel@tonic-gate while (count-- > 0) 3557c478bd9Sstevel@tonic-gate adjprintf(" %*d", 2, 0); 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "intr") / etime); 3587c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "syscall") / etime); 3597c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 4, kstat_delta(oldsys, newsys, "pswitch") / etime); 3607c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, 3617c478bd9Sstevel@tonic-gate kstat_delta(oldsys, newsys, "cpu_ticks_user") * percent_factor); 3627c478bd9Sstevel@tonic-gate adjprintf(" %*.0f", 2, kstat_delta(oldsys, newsys, "cpu_ticks_kernel") 3637c478bd9Sstevel@tonic-gate * percent_factor); 3647c478bd9Sstevel@tonic-gate adjprintf(" %*.0f\n", 2, (kstat_delta(oldsys, newsys, "cpu_ticks_idle") 3657c478bd9Sstevel@tonic-gate + kstat_delta(oldsys, newsys, "cpu_ticks_wait")) 3667c478bd9Sstevel@tonic-gate * percent_factor); 3677c478bd9Sstevel@tonic-gate (void) fflush(stdout); 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3717c478bd9Sstevel@tonic-gate static void 3727c478bd9Sstevel@tonic-gate print_disk(void *v, void *v2, void *d) 3737c478bd9Sstevel@tonic-gate { 3747c478bd9Sstevel@tonic-gate struct iodev_snapshot *iodev = (struct iodev_snapshot *)v2; 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate if (iodev == NULL) 3777c478bd9Sstevel@tonic-gate return; 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate (void) printf("%c%c ", iodev->is_name[0], iodev->is_name[2]); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3837c478bd9Sstevel@tonic-gate static void 3847c478bd9Sstevel@tonic-gate printhdr(int sig) 3857c478bd9Sstevel@tonic-gate { 3867c478bd9Sstevel@tonic-gate int i = df.if_max_iodevs - ss->s_nr_iodevs; 3877c478bd9Sstevel@tonic-gate 38800c76d6fStc35445 if (sig == SIGCONT) 38900c76d6fStc35445 caught_cont = 1; 39000c76d6fStc35445 3917c478bd9Sstevel@tonic-gate if (pflag) { 3927c478bd9Sstevel@tonic-gate (void) printf(" memory page "); 3937c478bd9Sstevel@tonic-gate (void) printf("executable anonymous filesystem \n"); 3947c478bd9Sstevel@tonic-gate (void) printf(" swap free re mf fr de sr "); 3957c478bd9Sstevel@tonic-gate (void) printf("epi epo epf api apo apf fpi fpo fpf\n"); 3967c478bd9Sstevel@tonic-gate lines = REPRINT; 3977c478bd9Sstevel@tonic-gate return; 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate (void) printf(" kthr memory page "); 4017c478bd9Sstevel@tonic-gate (void) printf("disk faults cpu\n"); 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate if (swflag) 4047c478bd9Sstevel@tonic-gate (void) printf(" r b w swap free si so pi po fr de sr "); 4057c478bd9Sstevel@tonic-gate else 4067c478bd9Sstevel@tonic-gate (void) printf(" r b w swap free re mf pi po fr de sr "); 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate (void) snapshot_walk(SNAP_IODEVS, NULL, ss, print_disk, NULL); 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate while (i-- > 0) 4117c478bd9Sstevel@tonic-gate (void) printf("-- "); 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate (void) printf(" in sy cs us sy id\n"); 4147c478bd9Sstevel@tonic-gate lines = REPRINT; 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate static void 4187c478bd9Sstevel@tonic-gate sum_out(char const *pretty, kstat_t *ks, char *name) 4197c478bd9Sstevel@tonic-gate { 4207c478bd9Sstevel@tonic-gate kstat_named_t *ksn = kstat_data_lookup(ks, name); 4217c478bd9Sstevel@tonic-gate if (ksn == NULL) { 4227c478bd9Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', '%s') failed", 4237c478bd9Sstevel@tonic-gate ks->ks_name, name); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate (void) printf("%9llu %s\n", ksn->value.ui64, pretty); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate static void 4307c478bd9Sstevel@tonic-gate dosum(struct sys_snapshot *ss) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate uint64_t total_faults; 4337c478bd9Sstevel@tonic-gate kstat_named_t *ksn; 4347c478bd9Sstevel@tonic-gate long double nchtotal; 4357c478bd9Sstevel@tonic-gate uint64_t nchhits; 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate sum_out("swap ins", &ss->ss_agg_vm, "swapin"); 4387c478bd9Sstevel@tonic-gate sum_out("swap outs", &ss->ss_agg_vm, "swapout"); 4397c478bd9Sstevel@tonic-gate sum_out("pages swapped in", &ss->ss_agg_vm, "pgswapin"); 4407c478bd9Sstevel@tonic-gate sum_out("pages swapped out", &ss->ss_agg_vm, "pgswapout"); 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate ksn = kstat_data_lookup(&ss->ss_agg_vm, "hat_fault"); 4437c478bd9Sstevel@tonic-gate if (ksn == NULL) { 4447c478bd9Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', 'hat_fault') failed", 4457c478bd9Sstevel@tonic-gate ss->ss_agg_vm.ks_name); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate total_faults = ksn->value.ui64; 4487c478bd9Sstevel@tonic-gate ksn = kstat_data_lookup(&ss->ss_agg_vm, "as_fault"); 4497c478bd9Sstevel@tonic-gate if (ksn == NULL) { 4507c478bd9Sstevel@tonic-gate fail(0, "kstat_data_lookup('%s', 'as_fault') failed", 4517c478bd9Sstevel@tonic-gate ss->ss_agg_vm.ks_name); 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate total_faults += ksn->value.ui64; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate (void) printf("%9llu total address trans. faults taken\n", 4567c478bd9Sstevel@tonic-gate total_faults); 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate sum_out("page ins", &ss->ss_agg_vm, "pgin"); 4597c478bd9Sstevel@tonic-gate sum_out("page outs", &ss->ss_agg_vm, "pgout"); 4607c478bd9Sstevel@tonic-gate sum_out("pages paged in", &ss->ss_agg_vm, "pgpgin"); 4617c478bd9Sstevel@tonic-gate sum_out("pages paged out", &ss->ss_agg_vm, "pgpgout"); 4627c478bd9Sstevel@tonic-gate sum_out("total reclaims", &ss->ss_agg_vm, "pgrec"); 4637c478bd9Sstevel@tonic-gate sum_out("reclaims from free list", &ss->ss_agg_vm, "pgfrec"); 4647c478bd9Sstevel@tonic-gate sum_out("micro (hat) faults", &ss->ss_agg_vm, "hat_fault"); 4657c478bd9Sstevel@tonic-gate sum_out("minor (as) faults", &ss->ss_agg_vm, "as_fault"); 4667c478bd9Sstevel@tonic-gate sum_out("major faults", &ss->ss_agg_vm, "maj_fault"); 4677c478bd9Sstevel@tonic-gate sum_out("copy-on-write faults", &ss->ss_agg_vm, "cow_fault"); 4687c478bd9Sstevel@tonic-gate sum_out("zero fill page faults", &ss->ss_agg_vm, "zfod"); 4697c478bd9Sstevel@tonic-gate sum_out("pages examined by the clock daemon", &ss->ss_agg_vm, "scan"); 4707c478bd9Sstevel@tonic-gate sum_out("revolutions of the clock hand", &ss->ss_agg_vm, "rev"); 4717c478bd9Sstevel@tonic-gate sum_out("pages freed by the clock daemon", &ss->ss_agg_vm, "dfree"); 4727c478bd9Sstevel@tonic-gate sum_out("forks", &ss->ss_agg_sys, "sysfork"); 4737c478bd9Sstevel@tonic-gate sum_out("vforks", &ss->ss_agg_sys, "sysvfork"); 4747c478bd9Sstevel@tonic-gate sum_out("execs", &ss->ss_agg_sys, "sysexec"); 4757c478bd9Sstevel@tonic-gate sum_out("cpu context switches", &ss->ss_agg_sys, "pswitch"); 4767c478bd9Sstevel@tonic-gate sum_out("device interrupts", &ss->ss_agg_sys, "intr"); 4777c478bd9Sstevel@tonic-gate sum_out("traps", &ss->ss_agg_sys, "trap"); 4787c478bd9Sstevel@tonic-gate sum_out("system calls", &ss->ss_agg_sys, "syscall"); 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate nchtotal = (long double) ss->ss_nc.ncs_hits.value.ui64 + 4817c478bd9Sstevel@tonic-gate (long double) ss->ss_nc.ncs_misses.value.ui64; 4827c478bd9Sstevel@tonic-gate nchhits = ss->ss_nc.ncs_hits.value.ui64; 4837c478bd9Sstevel@tonic-gate (void) printf("%9.0Lf total name lookups (cache hits %.0Lf%%)\n", 4847c478bd9Sstevel@tonic-gate nchtotal, nchhits / denom(nchtotal) * 100); 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate sum_out("user cpu", &ss->ss_agg_sys, "cpu_ticks_user"); 4877c478bd9Sstevel@tonic-gate sum_out("system cpu", &ss->ss_agg_sys, "cpu_ticks_kernel"); 4887c478bd9Sstevel@tonic-gate sum_out("idle cpu", &ss->ss_agg_sys, "cpu_ticks_idle"); 4897c478bd9Sstevel@tonic-gate sum_out("wait cpu", &ss->ss_agg_sys, "cpu_ticks_wait"); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate static void 4937c478bd9Sstevel@tonic-gate dointr(struct snapshot *ss) 4947c478bd9Sstevel@tonic-gate { 4957c478bd9Sstevel@tonic-gate size_t i; 4967c478bd9Sstevel@tonic-gate ulong_t total = 0; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate (void) printf("interrupt total rate\n"); 4997c478bd9Sstevel@tonic-gate (void) printf("--------------------------------\n"); 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate for (i = 0; i < ss->s_nr_intrs; i++) { 5027c478bd9Sstevel@tonic-gate (void) printf("%-12.8s %10lu %8.0f\n", 5037c478bd9Sstevel@tonic-gate ss->s_intrs[i].is_name, ss->s_intrs[i].is_total, 5047c478bd9Sstevel@tonic-gate ss->s_intrs[i].is_total / etime); 5057c478bd9Sstevel@tonic-gate total += ss->s_intrs[i].is_total; 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate (void) printf("--------------------------------\n"); 5097c478bd9Sstevel@tonic-gate (void) printf("Total %10lu %8.0f\n", total, total / etime); 5107c478bd9Sstevel@tonic-gate } 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate static void 51300c76d6fStc35445 docachestats(kstat_ctl_t *kc, hrtime_t interval, int forever) 5147c478bd9Sstevel@tonic-gate { 5157c478bd9Sstevel@tonic-gate struct snapshot *old; 5167c478bd9Sstevel@tonic-gate struct snapshot *new; 5177c478bd9Sstevel@tonic-gate int i; 51800c76d6fStc35445 hrtime_t start; 5197c478bd9Sstevel@tonic-gate 52000c76d6fStc35445 start = gethrtime(); 5217c478bd9Sstevel@tonic-gate old = acquire_snapshot(kc, SNAP_FLUSHES, NULL); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate if (iter == 0) { 5247c478bd9Sstevel@tonic-gate (void) printf("flush statistics: (totals)\n"); 5257c478bd9Sstevel@tonic-gate (void) printf("%8s%8s%8s%8s%8s%8s\n", 5267c478bd9Sstevel@tonic-gate "usr", "ctx", "rgn", "seg", "pag", "par"); 5277c478bd9Sstevel@tonic-gate (void) printf(" %7d %7d %7d %7d %7d %7d\n", 5287c478bd9Sstevel@tonic-gate old->s_flushes.f_usr, old->s_flushes.f_ctx, 5297c478bd9Sstevel@tonic-gate old->s_flushes.f_region, old->s_flushes.f_segment, 5307c478bd9Sstevel@tonic-gate old->s_flushes.f_page, old->s_flushes.f_partial); 5317c478bd9Sstevel@tonic-gate return; 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate (void) printf("flush statistics: (interval based)\n"); 5357c478bd9Sstevel@tonic-gate for (i = 0; i < iter; i++) { 5367c478bd9Sstevel@tonic-gate if (i % REPRINT == 0) 5377c478bd9Sstevel@tonic-gate (void) printf("%8s%8s%8s%8s%8s%8s\n", 5387c478bd9Sstevel@tonic-gate "usr", "ctx", "rgn", "seg", "pag", "par"); 5397c478bd9Sstevel@tonic-gate 54000c76d6fStc35445 /* Have a kip */ 54100c76d6fStc35445 sleep_until(&start, interval, forever, &caught_cont); 54200c76d6fStc35445 5437c478bd9Sstevel@tonic-gate new = acquire_snapshot(kc, SNAP_FLUSHES, NULL); 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate (void) printf(" %7d %7d %7d %7d %7d %7d\n", 5467c478bd9Sstevel@tonic-gate new->s_flushes.f_usr - old->s_flushes.f_usr, 5477c478bd9Sstevel@tonic-gate new->s_flushes.f_ctx - old->s_flushes.f_ctx, 5487c478bd9Sstevel@tonic-gate new->s_flushes.f_region - old->s_flushes.f_region, 5497c478bd9Sstevel@tonic-gate new->s_flushes.f_segment - old->s_flushes.f_segment, 5507c478bd9Sstevel@tonic-gate new->s_flushes.f_page - old->s_flushes.f_page, 5517c478bd9Sstevel@tonic-gate new->s_flushes.f_partial- old->s_flushes.f_partial); 5527c478bd9Sstevel@tonic-gate (void) fflush(stdout); 5537c478bd9Sstevel@tonic-gate free_snapshot(old); 5547c478bd9Sstevel@tonic-gate old = new; 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate static void 5597c478bd9Sstevel@tonic-gate usage(void) 5607c478bd9Sstevel@tonic-gate { 5617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5624944376cSJohn Levon "Usage: vmstat [-cipqsS] [-T d|u] [disk ...] " 5634944376cSJohn Levon "[interval [count]]\n"); 5647c478bd9Sstevel@tonic-gate exit(1); 5657c478bd9Sstevel@tonic-gate } 566