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