17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5b2d230ebSjc144527 * Common Development and Distribution License (the "License").
6b2d230ebSjc144527 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*f83fba1aSGowtham Thommandra * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate * sar generates a report either from an input data file or by invoking sadc to
327c478bd9Sstevel@tonic-gate * read system activity counters at the specified intervals.
337c478bd9Sstevel@tonic-gate *
347c478bd9Sstevel@tonic-gate * usage: sar [-ubdycwaqvmpgrkA] [-o file] t [n]
357c478bd9Sstevel@tonic-gate * sar [-ubdycwaqvmpgrkA][-s hh:mm][-e hh:mm][-i ss][-f file]
367c478bd9Sstevel@tonic-gate */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <sys/param.h>
397c478bd9Sstevel@tonic-gate #include <sys/stat.h>
407c478bd9Sstevel@tonic-gate #include <sys/sysinfo.h>
417c478bd9Sstevel@tonic-gate #include <sys/time.h>
427c478bd9Sstevel@tonic-gate #include <sys/types.h>
437c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
447c478bd9Sstevel@tonic-gate #include <sys/wait.h>
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate #include <ctype.h>
477c478bd9Sstevel@tonic-gate #include <errno.h>
487c478bd9Sstevel@tonic-gate #include <fcntl.h>
497c478bd9Sstevel@tonic-gate #include <limits.h>
507c478bd9Sstevel@tonic-gate #include <signal.h>
517c478bd9Sstevel@tonic-gate #include <stdarg.h>
527c478bd9Sstevel@tonic-gate #include <stdio.h>
537c478bd9Sstevel@tonic-gate #include <stdlib.h>
547c478bd9Sstevel@tonic-gate #include <string.h>
557c478bd9Sstevel@tonic-gate #include <time.h>
567c478bd9Sstevel@tonic-gate #include <unistd.h>
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate #include "sa.h"
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate #define PGTOBLK(x) ((x) * (pagesize >> 9))
617c478bd9Sstevel@tonic-gate #define BLKTOPG(x) ((x) / (pagesize >> 9))
627c478bd9Sstevel@tonic-gate #define BLKS(x) ((x) >> 9)
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate static void prpass(int);
657c478bd9Sstevel@tonic-gate static void prtopt(void);
667c478bd9Sstevel@tonic-gate static void prtavg(void);
677c478bd9Sstevel@tonic-gate static void prttim(void);
687c478bd9Sstevel@tonic-gate static void prtmachid(void);
697c478bd9Sstevel@tonic-gate static void prthdg(void);
707c478bd9Sstevel@tonic-gate static void tsttab(void);
717c478bd9Sstevel@tonic-gate static void update_counters(void);
727c478bd9Sstevel@tonic-gate static void usage(void);
737c478bd9Sstevel@tonic-gate static void fail(int, char *, ...);
747c478bd9Sstevel@tonic-gate static void safe_zalloc(void **, int, int);
757c478bd9Sstevel@tonic-gate static int safe_read(int, void *, size_t);
767c478bd9Sstevel@tonic-gate static void safe_write(int, void *, size_t);
777c478bd9Sstevel@tonic-gate static int safe_strtoi(char const *, char *);
78b9b602f4Sjs198686 static void ulong_delta(uint64_t *, uint64_t *, uint64_t *, uint64_t *,
797c478bd9Sstevel@tonic-gate int, int);
807c478bd9Sstevel@tonic-gate static float denom(float);
817c478bd9Sstevel@tonic-gate static float freq(float, float);
827c478bd9Sstevel@tonic-gate
83b9b602f4Sjs198686 static struct sa64 nx, ox, ax, dx;
847c478bd9Sstevel@tonic-gate static iodevinfo_t *nxio, *oxio, *axio, *dxio;
857c478bd9Sstevel@tonic-gate static struct tm *curt, args, arge;
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate static int sflg, eflg, iflg, oflg, fflg;
887c478bd9Sstevel@tonic-gate static int realtime, passno = 0, do_disk;
897c478bd9Sstevel@tonic-gate static int t = 0, n = 0, lines = 0;
907c478bd9Sstevel@tonic-gate static int hz;
917c478bd9Sstevel@tonic-gate static int niodevs;
927c478bd9Sstevel@tonic-gate static int tabflg;
937c478bd9Sstevel@tonic-gate static char options[30], fopt[30];
947c478bd9Sstevel@tonic-gate static float tdiff, sec_diff, totsec_diff = 0.0, percent;
957c478bd9Sstevel@tonic-gate static float start_time, end_time, isec;
967c478bd9Sstevel@tonic-gate static int fin, fout;
977c478bd9Sstevel@tonic-gate static pid_t childid;
987c478bd9Sstevel@tonic-gate static int pipedes[2];
997c478bd9Sstevel@tonic-gate static char arg1[10], arg2[10];
1007c478bd9Sstevel@tonic-gate static int pagesize;
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate /*
1037c478bd9Sstevel@tonic-gate * To avoid overflow in the kmem allocation data, declare a copy of the
1047c478bd9Sstevel@tonic-gate * main kmeminfo_t type with larger data types. Use this for storing
1057c478bd9Sstevel@tonic-gate * the data held to display average values
1067c478bd9Sstevel@tonic-gate */
1077c478bd9Sstevel@tonic-gate static struct kmeminfo_l
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate u_longlong_t km_mem[KMEM_NCLASS];
1107c478bd9Sstevel@tonic-gate u_longlong_t km_alloc[KMEM_NCLASS];
1117c478bd9Sstevel@tonic-gate u_longlong_t km_fail[KMEM_NCLASS];
1127c478bd9Sstevel@tonic-gate } kmi;
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)1157c478bd9Sstevel@tonic-gate main(int argc, char **argv)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate char flnm[PATH_MAX], ofile[PATH_MAX];
1187c478bd9Sstevel@tonic-gate char ccc;
1197c478bd9Sstevel@tonic-gate time_t temp;
1207c478bd9Sstevel@tonic-gate int i, jj = 0;
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate pagesize = sysconf(_SC_PAGESIZE);
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate * Process options with arguments and pack options
1267c478bd9Sstevel@tonic-gate * without arguments.
1277c478bd9Sstevel@tonic-gate */
1287c478bd9Sstevel@tonic-gate while ((i = getopt(argc, argv, "ubdycwaqvmpgrkAo:s:e:i:f:")) != EOF)
1297c478bd9Sstevel@tonic-gate switch (ccc = (char)i) {
1307c478bd9Sstevel@tonic-gate case 'o':
1317c478bd9Sstevel@tonic-gate oflg++;
1327c478bd9Sstevel@tonic-gate if (strlcpy(ofile, optarg, sizeof (ofile)) >=
1337c478bd9Sstevel@tonic-gate sizeof (ofile)) {
1347c478bd9Sstevel@tonic-gate fail(2, "-o filename is too long: %s", optarg);
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate break;
1377c478bd9Sstevel@tonic-gate case 's':
1387c478bd9Sstevel@tonic-gate if (sscanf(optarg, "%d:%d:%d",
1397c478bd9Sstevel@tonic-gate &args.tm_hour, &args.tm_min, &args.tm_sec) < 1)
1407c478bd9Sstevel@tonic-gate fail(0, "-%c %s -- illegal option argument",
1417c478bd9Sstevel@tonic-gate ccc, optarg);
1427c478bd9Sstevel@tonic-gate else {
1437c478bd9Sstevel@tonic-gate sflg++,
1447c478bd9Sstevel@tonic-gate start_time = args.tm_hour*3600.0 +
1457c478bd9Sstevel@tonic-gate args.tm_min*60.0 +
1467c478bd9Sstevel@tonic-gate args.tm_sec;
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate break;
1497c478bd9Sstevel@tonic-gate case 'e':
1507c478bd9Sstevel@tonic-gate if (sscanf(optarg, "%d:%d:%d",
1517c478bd9Sstevel@tonic-gate &arge.tm_hour, &arge.tm_min, &arge.tm_sec) < 1)
1527c478bd9Sstevel@tonic-gate fail(0, "-%c %s -- illegal option argument",
1537c478bd9Sstevel@tonic-gate ccc, optarg);
1547c478bd9Sstevel@tonic-gate else {
1557c478bd9Sstevel@tonic-gate eflg++;
1567c478bd9Sstevel@tonic-gate end_time = arge.tm_hour*3600.0 +
1577c478bd9Sstevel@tonic-gate arge.tm_min*60.0 +
1587c478bd9Sstevel@tonic-gate arge.tm_sec;
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate break;
1617c478bd9Sstevel@tonic-gate case 'i':
1627c478bd9Sstevel@tonic-gate if (sscanf(optarg, "%f", &isec) < 1)
1637c478bd9Sstevel@tonic-gate fail(0, "-%c %s -- illegal option argument",
1647c478bd9Sstevel@tonic-gate ccc, optarg);
1657c478bd9Sstevel@tonic-gate else {
1667c478bd9Sstevel@tonic-gate if (isec > 0.0)
1677c478bd9Sstevel@tonic-gate iflg++;
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate break;
1707c478bd9Sstevel@tonic-gate case 'f':
1717c478bd9Sstevel@tonic-gate fflg++;
1727c478bd9Sstevel@tonic-gate if (strlcpy(flnm, optarg, sizeof (flnm)) >=
1737c478bd9Sstevel@tonic-gate sizeof (ofile)) {
1747c478bd9Sstevel@tonic-gate fail(2, "-f filename is too long: %s", optarg);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate break;
1777c478bd9Sstevel@tonic-gate case '?':
1787c478bd9Sstevel@tonic-gate usage();
1797c478bd9Sstevel@tonic-gate exit(1);
1807c478bd9Sstevel@tonic-gate break;
1817c478bd9Sstevel@tonic-gate default:
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate /*
1847c478bd9Sstevel@tonic-gate * Check for repeated options. To make sure
1857c478bd9Sstevel@tonic-gate * that options[30] does not overflow.
1867c478bd9Sstevel@tonic-gate */
1877c478bd9Sstevel@tonic-gate if (strchr(options, ccc) == NULL)
1887c478bd9Sstevel@tonic-gate (void) strncat(options, &ccc, 1);
1897c478bd9Sstevel@tonic-gate break;
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate /*
1937c478bd9Sstevel@tonic-gate * Are starting and ending times consistent?
1947c478bd9Sstevel@tonic-gate */
1957c478bd9Sstevel@tonic-gate if ((sflg) && (eflg) && (end_time <= start_time))
1967c478bd9Sstevel@tonic-gate fail(0, "ending time <= starting time");
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate /*
1997c478bd9Sstevel@tonic-gate * Determine if t and n arguments are given, and whether to run in real
2007c478bd9Sstevel@tonic-gate * time or from a file.
2017c478bd9Sstevel@tonic-gate */
2027c478bd9Sstevel@tonic-gate switch (argc - optind) {
2037c478bd9Sstevel@tonic-gate case 0: /* Get input data from file */
2047c478bd9Sstevel@tonic-gate if (fflg == 0) {
2057c478bd9Sstevel@tonic-gate temp = time(NULL);
2067c478bd9Sstevel@tonic-gate curt = localtime(&temp);
2077c478bd9Sstevel@tonic-gate (void) snprintf(flnm, PATH_MAX, "/var/adm/sa/sa%.2d",
2087c478bd9Sstevel@tonic-gate curt->tm_mday);
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate if ((fin = open(flnm, 0)) == -1)
2117c478bd9Sstevel@tonic-gate fail(1, "can't open %s", flnm);
2127c478bd9Sstevel@tonic-gate break;
2137c478bd9Sstevel@tonic-gate case 1: /* Real time data; one cycle */
2147c478bd9Sstevel@tonic-gate realtime++;
2157c478bd9Sstevel@tonic-gate t = safe_strtoi(argv[optind], "invalid sampling interval");
2167c478bd9Sstevel@tonic-gate n = 2;
2177c478bd9Sstevel@tonic-gate break;
2187c478bd9Sstevel@tonic-gate case 2: /* Real time data; specified cycles */
2197c478bd9Sstevel@tonic-gate default:
2207c478bd9Sstevel@tonic-gate realtime++;
2217c478bd9Sstevel@tonic-gate t = safe_strtoi(argv[optind], "invalid sampling interval");
2227c478bd9Sstevel@tonic-gate n = 1 + safe_strtoi(argv[optind+1], "invalid sample count");
2237c478bd9Sstevel@tonic-gate break;
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate /*
2277c478bd9Sstevel@tonic-gate * "u" is the default option, which displays CPU utilization.
2287c478bd9Sstevel@tonic-gate */
2297c478bd9Sstevel@tonic-gate if (strlen(options) == 0)
2307c478bd9Sstevel@tonic-gate (void) strcpy(options, "u");
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate /*
2337c478bd9Sstevel@tonic-gate * "A" means all data options.
2347c478bd9Sstevel@tonic-gate */
2357c478bd9Sstevel@tonic-gate if (strchr(options, 'A') != NULL)
2367c478bd9Sstevel@tonic-gate (void) strcpy(options, "udqbwcayvmpgrk");
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate if (realtime) {
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate * Get input data from sadc via pipe.
2417c478bd9Sstevel@tonic-gate */
2427c478bd9Sstevel@tonic-gate if (t <= 0)
2437c478bd9Sstevel@tonic-gate fail(0, "sampling interval t <= 0 sec");
2447c478bd9Sstevel@tonic-gate if (n < 2)
2457c478bd9Sstevel@tonic-gate fail(0, "number of sample intervals n <= 0");
2467c478bd9Sstevel@tonic-gate (void) sprintf(arg1, "%d", t);
2477c478bd9Sstevel@tonic-gate (void) sprintf(arg2, "%d", n);
2487c478bd9Sstevel@tonic-gate if (pipe(pipedes) == -1)
2497c478bd9Sstevel@tonic-gate fail(1, "pipe failed");
2507c478bd9Sstevel@tonic-gate if ((childid = fork()) == 0) {
2517c478bd9Sstevel@tonic-gate /*
2527c478bd9Sstevel@tonic-gate * Child: shift pipedes[write] to stdout,
2537c478bd9Sstevel@tonic-gate * and close the pipe entries.
2547c478bd9Sstevel@tonic-gate */
2557c478bd9Sstevel@tonic-gate (void) dup2(pipedes[1], 1);
2567c478bd9Sstevel@tonic-gate if (pipedes[0] != 1)
2577c478bd9Sstevel@tonic-gate (void) close(pipedes[0]);
2587c478bd9Sstevel@tonic-gate if (pipedes[1] != 1)
2597c478bd9Sstevel@tonic-gate (void) close(pipedes[1]);
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate if (execlp("/usr/lib/sa/sadc",
2627c478bd9Sstevel@tonic-gate "/usr/lib/sa/sadc", arg1, arg2, 0) == -1)
2637c478bd9Sstevel@tonic-gate fail(1, "exec of /usr/lib/sa/sadc failed");
2647c478bd9Sstevel@tonic-gate } else if (childid == -1) {
2657c478bd9Sstevel@tonic-gate fail(1, "Could not fork to exec sadc");
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate /*
2687c478bd9Sstevel@tonic-gate * Parent: close unused output.
2697c478bd9Sstevel@tonic-gate */
2707c478bd9Sstevel@tonic-gate fin = pipedes[0];
2717c478bd9Sstevel@tonic-gate (void) close(pipedes[1]);
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate if (oflg) {
2757c478bd9Sstevel@tonic-gate if (strcmp(ofile, flnm) == 0)
2767c478bd9Sstevel@tonic-gate fail(0, "output file name same as input file name");
2777c478bd9Sstevel@tonic-gate fout = creat(ofile, 00644);
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate
2807c478bd9Sstevel@tonic-gate hz = sysconf(_SC_CLK_TCK);
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate nxio = oxio = dxio = axio = NULL;
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate if (realtime) {
2857c478bd9Sstevel@tonic-gate /*
2867c478bd9Sstevel@tonic-gate * Make single pass, processing all options.
2877c478bd9Sstevel@tonic-gate */
2887c478bd9Sstevel@tonic-gate (void) strcpy(fopt, options);
2897c478bd9Sstevel@tonic-gate passno++;
2907c478bd9Sstevel@tonic-gate prpass(realtime);
2917c478bd9Sstevel@tonic-gate (void) kill(childid, SIGINT);
2927c478bd9Sstevel@tonic-gate (void) wait(NULL);
2937c478bd9Sstevel@tonic-gate } else {
2947c478bd9Sstevel@tonic-gate /*
2957c478bd9Sstevel@tonic-gate * Make multiple passes, one for each option.
2967c478bd9Sstevel@tonic-gate */
2977c478bd9Sstevel@tonic-gate while (strlen(strncpy(fopt, &options[jj++], 1))) {
2987c478bd9Sstevel@tonic-gate if (lseek(fin, 0, SEEK_SET) == (off_t)-1)
2997c478bd9Sstevel@tonic-gate fail(0, "lseek failed");
3007c478bd9Sstevel@tonic-gate passno++;
3017c478bd9Sstevel@tonic-gate prpass(realtime);
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate return (0);
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate /*
309b9b602f4Sjs198686 * Convert array of 32-bit uints to 64-bit uints
310b9b602f4Sjs198686 */
311b9b602f4Sjs198686 static void
convert_32to64(uint64_t * dst,uint_t * src,int size)312b9b602f4Sjs198686 convert_32to64(uint64_t *dst, uint_t *src, int size)
313b9b602f4Sjs198686 {
314b9b602f4Sjs198686 for (; size > 0; size--)
315b9b602f4Sjs198686 *dst++ = (uint64_t)(*src++);
316b9b602f4Sjs198686 }
317b9b602f4Sjs198686
318b9b602f4Sjs198686 /*
319e83e7a19Srr204483 * Convert array of 64-bit uints to 32-bit uints
320e83e7a19Srr204483 */
321e83e7a19Srr204483 static void
convert_64to32(uint_t * dst,uint64_t * src,int size)322e83e7a19Srr204483 convert_64to32(uint_t *dst, uint64_t *src, int size)
323e83e7a19Srr204483 {
324e83e7a19Srr204483 for (; size > 0; size--)
325e83e7a19Srr204483 *dst++ = (uint32_t)(*src++);
326e83e7a19Srr204483 }
327e83e7a19Srr204483
328e83e7a19Srr204483 /*
3297c478bd9Sstevel@tonic-gate * Read records from input, classify, and decide on printing.
3307c478bd9Sstevel@tonic-gate */
3317c478bd9Sstevel@tonic-gate static void
prpass(int input_pipe)3327c478bd9Sstevel@tonic-gate prpass(int input_pipe)
3337c478bd9Sstevel@tonic-gate {
3347c478bd9Sstevel@tonic-gate size_t size;
3357c478bd9Sstevel@tonic-gate int i, j, state_change, recno = 0;
3367c478bd9Sstevel@tonic-gate kid_t kid;
3377c478bd9Sstevel@tonic-gate float trec, tnext = 0;
3387c478bd9Sstevel@tonic-gate ulong_t old_niodevs = 0, prev_niodevs = 0;
3397c478bd9Sstevel@tonic-gate iodevinfo_t *aio, *dio, *oio;
3407c478bd9Sstevel@tonic-gate struct stat in_stat;
341b9b602f4Sjs198686 struct sa tx;
342b9b602f4Sjs198686 uint64_t ts, te; /* time interval start and end */
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate do_disk = (strchr(fopt, 'd') != NULL);
3457c478bd9Sstevel@tonic-gate if (!input_pipe && fstat(fin, &in_stat) == -1)
3467c478bd9Sstevel@tonic-gate fail(1, "unable to stat data file");
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate if (sflg)
3497c478bd9Sstevel@tonic-gate tnext = start_time;
3507c478bd9Sstevel@tonic-gate
351b9b602f4Sjs198686 while (safe_read(fin, &tx, sizeof (struct sa))) {
352b9b602f4Sjs198686 /*
353e83e7a19Srr204483 * First, we convert 32-bit tx to 64-bit nx structure
354b9b602f4Sjs198686 * which is used later. Conversion could be done
355b9b602f4Sjs198686 * after initial operations, right before calculations,
356b9b602f4Sjs198686 * but it would introduce additional juggling with vars.
357b9b602f4Sjs198686 * Thus, we convert all data now, and don't care about
358b9b602f4Sjs198686 * tx any further.
359b9b602f4Sjs198686 */
360b9b602f4Sjs198686 nx.valid = tx.valid;
361b9b602f4Sjs198686 nx.ts = tx.ts;
362b9b602f4Sjs198686 convert_32to64((uint64_t *)&nx.csi, (uint_t *)&tx.csi,
363b9b602f4Sjs198686 sizeof (tx.csi) / sizeof (uint_t));
364b9b602f4Sjs198686 convert_32to64((uint64_t *)&nx.cvmi, (uint_t *)&tx.cvmi,
365b9b602f4Sjs198686 sizeof (tx.cvmi) / sizeof (uint_t));
366b9b602f4Sjs198686 convert_32to64((uint64_t *)&nx.si, (uint_t *)&tx.si,
367b9b602f4Sjs198686 sizeof (tx.si) / sizeof (uint_t));
368b9b602f4Sjs198686 (void) memcpy(&nx.vmi, &tx.vmi,
369b9b602f4Sjs198686 sizeof (tx) - (((char *)&tx.vmi) - ((char *)&tx)));
3707c478bd9Sstevel@tonic-gate /*
3717c478bd9Sstevel@tonic-gate * sadc is the only utility used to generate sar data
3727c478bd9Sstevel@tonic-gate * and it uses the valid field as follows:
3737c478bd9Sstevel@tonic-gate * 0 - dummy record
3747c478bd9Sstevel@tonic-gate * 1 - data record
3757c478bd9Sstevel@tonic-gate * We can use this fact to improve sar's ability to detect
3767c478bd9Sstevel@tonic-gate * bad data, since any value apart from 0 or 1 can be
3777c478bd9Sstevel@tonic-gate * interpreted as invalid data.
3787c478bd9Sstevel@tonic-gate */
3797c478bd9Sstevel@tonic-gate if (nx.valid != 0 && nx.valid != 1)
3807c478bd9Sstevel@tonic-gate fail(2, "data file not in sar format");
3817c478bd9Sstevel@tonic-gate state_change = 0;
3827c478bd9Sstevel@tonic-gate niodevs = nx.niodevs;
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate * niodevs has the value of current number of devices
3857c478bd9Sstevel@tonic-gate * from nx structure.
3867c478bd9Sstevel@tonic-gate *
3877c478bd9Sstevel@tonic-gate * The following 'if' condition is to decide whether memory
3887c478bd9Sstevel@tonic-gate * has to be allocated or not if already allocated memory is
3897c478bd9Sstevel@tonic-gate * bigger or smaller than memory needed to store the current
3907c478bd9Sstevel@tonic-gate * niodevs details in memory.
3917c478bd9Sstevel@tonic-gate *
3927c478bd9Sstevel@tonic-gate * when first while loop starts, pre_niodevs has 0 and then
3937c478bd9Sstevel@tonic-gate * always get initialized to the current number of devices
3947c478bd9Sstevel@tonic-gate * from nx.niodevs if it is different from previously read
3957c478bd9Sstevel@tonic-gate * niodevs.
3967c478bd9Sstevel@tonic-gate *
3977c478bd9Sstevel@tonic-gate * if the current niodevs has the same value of previously
3987c478bd9Sstevel@tonic-gate * allocated memory i.e, for prev_niodevs, it skips the
3997c478bd9Sstevel@tonic-gate * following 'if' loop or otherwise it allocates memory for
4007c478bd9Sstevel@tonic-gate * current devises (niodevs) and stores that value in
4017c478bd9Sstevel@tonic-gate * prev_niodevs for next time when loop continues to read
4027c478bd9Sstevel@tonic-gate * from the file.
4037c478bd9Sstevel@tonic-gate */
4047c478bd9Sstevel@tonic-gate if (niodevs != prev_niodevs) {
4057c478bd9Sstevel@tonic-gate off_t curr_pos;
4067c478bd9Sstevel@tonic-gate /*
4077c478bd9Sstevel@tonic-gate * The required buffer size must fit in a size_t.
4087c478bd9Sstevel@tonic-gate */
4097c478bd9Sstevel@tonic-gate if (SIZE_MAX / sizeof (iodevinfo_t) < niodevs)
4107c478bd9Sstevel@tonic-gate fail(2, "insufficient address space to hold "
4117c478bd9Sstevel@tonic-gate "%lu device records", niodevs);
4127c478bd9Sstevel@tonic-gate size = niodevs * sizeof (iodevinfo_t);
4137c478bd9Sstevel@tonic-gate prev_niodevs = niodevs;
4147c478bd9Sstevel@tonic-gate /*
4157c478bd9Sstevel@tonic-gate * The data file must exceed this size to be valid.
4167c478bd9Sstevel@tonic-gate */
4177c478bd9Sstevel@tonic-gate if (!input_pipe) {
4187c478bd9Sstevel@tonic-gate if ((curr_pos = lseek(fin, 0, SEEK_CUR)) ==
4197c478bd9Sstevel@tonic-gate (off_t)-1)
4207c478bd9Sstevel@tonic-gate fail(1, "lseek failed");
4217c478bd9Sstevel@tonic-gate if (in_stat.st_size < curr_pos ||
4227c478bd9Sstevel@tonic-gate size > in_stat.st_size - curr_pos)
4237c478bd9Sstevel@tonic-gate fail(2, "data file corrupt; specified size"
4247c478bd9Sstevel@tonic-gate "exceeds actual");
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate safe_zalloc((void **)&nxio, size, 1);
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate if (niodevs != old_niodevs)
4307c478bd9Sstevel@tonic-gate state_change = 1;
4317c478bd9Sstevel@tonic-gate for (i = 0; i < niodevs; i++) {
4327c478bd9Sstevel@tonic-gate if (safe_read(fin, &nxio[i], sizeof (iodevinfo_t)) == 0)
4337c478bd9Sstevel@tonic-gate fail(1, "premature end-of-file seen");
4347c478bd9Sstevel@tonic-gate if (i < old_niodevs &&
4357c478bd9Sstevel@tonic-gate nxio[i].ks.ks_kid != oxio[i].ks.ks_kid)
4367c478bd9Sstevel@tonic-gate state_change = 1;
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate curt = localtime(&nx.ts);
4397c478bd9Sstevel@tonic-gate trec = curt->tm_hour * 3600.0 +
4407c478bd9Sstevel@tonic-gate curt->tm_min * 60.0 +
4417c478bd9Sstevel@tonic-gate curt->tm_sec;
4427c478bd9Sstevel@tonic-gate if ((recno == 0) && (trec < start_time))
4437c478bd9Sstevel@tonic-gate continue;
4447c478bd9Sstevel@tonic-gate if ((eflg) && (trec > end_time))
4457c478bd9Sstevel@tonic-gate break;
4467c478bd9Sstevel@tonic-gate if ((oflg) && (passno == 1)) {
447e83e7a19Srr204483 /*
448e83e7a19Srr204483 * The calculated values are stroed in nx strcuture.
449e83e7a19Srr204483 * Convert 64-bit nx to 32-bit tx structure.
450e83e7a19Srr204483 */
451e83e7a19Srr204483 tx.valid = nx.valid;
452e83e7a19Srr204483 tx.ts = nx.ts;
453e83e7a19Srr204483 convert_64to32((uint_t *)&tx.csi, (uint64_t *)&nx.csi,
454e83e7a19Srr204483 sizeof (nx.csi) / sizeof (uint64_t));
455e83e7a19Srr204483 convert_64to32((uint_t *)&tx.cvmi, (uint64_t *)&nx.cvmi,
456e83e7a19Srr204483 sizeof (nx.cvmi) / sizeof (uint64_t));
457e83e7a19Srr204483 convert_64to32((uint_t *)&tx.si, (uint64_t *)&nx.si,
458e83e7a19Srr204483 sizeof (nx.si) / sizeof (uint64_t));
459e83e7a19Srr204483 (void) memcpy(&tx.vmi, &nx.vmi,
460e83e7a19Srr204483 sizeof (nx) - (((char *)&nx.vmi) - ((char *)&nx)));
461e83e7a19Srr204483 if (tx.valid != 0 && tx.valid != 1)
462e83e7a19Srr204483 fail(2, "data file not in sar format");
463e83e7a19Srr204483
464e83e7a19Srr204483 safe_write(fout, &tx, sizeof (struct sa));
4657c478bd9Sstevel@tonic-gate for (i = 0; i < niodevs; i++)
4667c478bd9Sstevel@tonic-gate safe_write(fout, &nxio[i],
4677c478bd9Sstevel@tonic-gate sizeof (iodevinfo_t));
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate if (recno == 0) {
4717c478bd9Sstevel@tonic-gate if (passno == 1)
4727c478bd9Sstevel@tonic-gate prtmachid();
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate prthdg();
4757c478bd9Sstevel@tonic-gate recno = 1;
4767c478bd9Sstevel@tonic-gate if ((iflg) && (tnext == 0))
4777c478bd9Sstevel@tonic-gate tnext = trec;
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate if (nx.valid == 0) {
4817c478bd9Sstevel@tonic-gate /*
4827c478bd9Sstevel@tonic-gate * This dummy record signifies system restart
4837c478bd9Sstevel@tonic-gate * New initial values of counters follow in next
4847c478bd9Sstevel@tonic-gate * record.
4857c478bd9Sstevel@tonic-gate */
4867c478bd9Sstevel@tonic-gate if (!realtime) {
4877c478bd9Sstevel@tonic-gate prttim();
4887c478bd9Sstevel@tonic-gate (void) printf("\tunix restarts\n");
4897c478bd9Sstevel@tonic-gate recno = 1;
4907c478bd9Sstevel@tonic-gate continue;
4917c478bd9Sstevel@tonic-gate }
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate if ((iflg) && (trec < tnext))
4947c478bd9Sstevel@tonic-gate continue;
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate if (state_change) {
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * Either the number of devices or the ordering of
4997c478bd9Sstevel@tonic-gate * the kstats has changed. We need to re-organise
5007c478bd9Sstevel@tonic-gate * the layout of our avg/delta arrays so that we
5017c478bd9Sstevel@tonic-gate * can cope with this in update_counters().
5027c478bd9Sstevel@tonic-gate */
5037c478bd9Sstevel@tonic-gate size = niodevs * sizeof (iodevinfo_t);
5047c478bd9Sstevel@tonic-gate safe_zalloc((void *)&aio, size, 0);
5057c478bd9Sstevel@tonic-gate safe_zalloc((void *)&dio, size, 0);
5067c478bd9Sstevel@tonic-gate safe_zalloc((void *)&oio, size, 0);
5077c478bd9Sstevel@tonic-gate
5087c478bd9Sstevel@tonic-gate /*
5097c478bd9Sstevel@tonic-gate * Loop through all the newly read iodev's, locate
5107c478bd9Sstevel@tonic-gate * the corresponding entry in the old arrays and
5117c478bd9Sstevel@tonic-gate * copy the entries into the same bucket of the
5127c478bd9Sstevel@tonic-gate * new arrays.
5137c478bd9Sstevel@tonic-gate */
5147c478bd9Sstevel@tonic-gate for (i = 0; i < niodevs; i++) {
5157c478bd9Sstevel@tonic-gate kid = nxio[i].ks.ks_kid;
5167c478bd9Sstevel@tonic-gate for (j = 0; j < old_niodevs; j++) {
5177c478bd9Sstevel@tonic-gate if (oxio[j].ks.ks_kid == kid) {
5187c478bd9Sstevel@tonic-gate oio[i] = oxio[j];
5197c478bd9Sstevel@tonic-gate aio[i] = axio[j];
5207c478bd9Sstevel@tonic-gate dio[i] = dxio[j];
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate }
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate
5257c478bd9Sstevel@tonic-gate free(axio);
5267c478bd9Sstevel@tonic-gate free(oxio);
5277c478bd9Sstevel@tonic-gate free(dxio);
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate axio = aio;
5307c478bd9Sstevel@tonic-gate oxio = oio;
5317c478bd9Sstevel@tonic-gate dxio = dio;
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate old_niodevs = niodevs;
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate if (recno++ > 1) {
5377c478bd9Sstevel@tonic-gate ts = ox.csi.cpu[0] + ox.csi.cpu[1] +
5387c478bd9Sstevel@tonic-gate ox.csi.cpu[2] + ox.csi.cpu[3];
5397c478bd9Sstevel@tonic-gate te = nx.csi.cpu[0] + nx.csi.cpu[1] +
5407c478bd9Sstevel@tonic-gate nx.csi.cpu[2] + nx.csi.cpu[3];
5417c478bd9Sstevel@tonic-gate tdiff = (float)(te - ts);
5427c478bd9Sstevel@tonic-gate sec_diff = tdiff / hz;
5437c478bd9Sstevel@tonic-gate percent = 100.0 / tdiff;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate /*
5467c478bd9Sstevel@tonic-gate * If the CPU stat counters have rolled
5477c478bd9Sstevel@tonic-gate * backward, this is our best indication that
5487c478bd9Sstevel@tonic-gate * a CPU has been offlined. We don't have
5497c478bd9Sstevel@tonic-gate * enough data to compute a sensible delta, so
5507c478bd9Sstevel@tonic-gate * toss out this interval, but compute the next
5517c478bd9Sstevel@tonic-gate * interval's delta from these values.
5527c478bd9Sstevel@tonic-gate */
5537c478bd9Sstevel@tonic-gate if (tdiff <= 0) {
5547c478bd9Sstevel@tonic-gate ox = nx;
5557c478bd9Sstevel@tonic-gate continue;
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate update_counters();
5587c478bd9Sstevel@tonic-gate prtopt();
5597c478bd9Sstevel@tonic-gate lines++;
5607c478bd9Sstevel@tonic-gate if (passno == 1)
5617c478bd9Sstevel@tonic-gate totsec_diff += sec_diff;
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate ox = nx; /* Age the data */
5647c478bd9Sstevel@tonic-gate (void) memcpy(oxio, nxio, niodevs * sizeof (iodevinfo_t));
5657c478bd9Sstevel@tonic-gate if (isec > 0)
5667c478bd9Sstevel@tonic-gate while (tnext <= trec)
5677c478bd9Sstevel@tonic-gate tnext += isec;
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate /*
5707c478bd9Sstevel@tonic-gate * After this place, all functions are using niodevs to access the
5717c478bd9Sstevel@tonic-gate * memory for device details. Here, old_niodevs has the correct value
5727c478bd9Sstevel@tonic-gate * of memory allocated for storing device information. Since niodevs
5737c478bd9Sstevel@tonic-gate * doesn't have correct value, sometimes, it was corrupting memory.
5747c478bd9Sstevel@tonic-gate */
5757c478bd9Sstevel@tonic-gate niodevs = old_niodevs;
5767c478bd9Sstevel@tonic-gate if (lines > 1)
5777c478bd9Sstevel@tonic-gate prtavg();
5787c478bd9Sstevel@tonic-gate (void) memset(&ax, 0, sizeof (ax)); /* Zero out the accumulators. */
5797c478bd9Sstevel@tonic-gate (void) memset(&kmi, 0, sizeof (kmi));
5807c478bd9Sstevel@tonic-gate lines = 0;
5817c478bd9Sstevel@tonic-gate /*
5827c478bd9Sstevel@tonic-gate * axio will not be allocated if the user specified -e or -s, and
5837c478bd9Sstevel@tonic-gate * no records in the file fell inside the specified time range.
5847c478bd9Sstevel@tonic-gate */
5857c478bd9Sstevel@tonic-gate if (axio) {
5867c478bd9Sstevel@tonic-gate (void) memset(axio, 0, niodevs * sizeof (iodevinfo_t));
5877c478bd9Sstevel@tonic-gate }
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate
5907c478bd9Sstevel@tonic-gate /*
5917c478bd9Sstevel@tonic-gate * Print time label routine.
5927c478bd9Sstevel@tonic-gate */
5937c478bd9Sstevel@tonic-gate static void
prttim(void)5947c478bd9Sstevel@tonic-gate prttim(void)
5957c478bd9Sstevel@tonic-gate {
5967c478bd9Sstevel@tonic-gate curt = localtime(&nx.ts);
5977c478bd9Sstevel@tonic-gate (void) printf("%.2d:%.2d:%.2d", curt->tm_hour, curt->tm_min,
5987c478bd9Sstevel@tonic-gate curt->tm_sec);
5997c478bd9Sstevel@tonic-gate tabflg = 1;
6007c478bd9Sstevel@tonic-gate }
6017c478bd9Sstevel@tonic-gate
6027c478bd9Sstevel@tonic-gate /*
6037c478bd9Sstevel@tonic-gate * Test if 8-spaces to be added routine.
6047c478bd9Sstevel@tonic-gate */
6057c478bd9Sstevel@tonic-gate static void
tsttab(void)6067c478bd9Sstevel@tonic-gate tsttab(void)
6077c478bd9Sstevel@tonic-gate {
6087c478bd9Sstevel@tonic-gate if (tabflg == 0)
6097c478bd9Sstevel@tonic-gate (void) printf(" ");
6107c478bd9Sstevel@tonic-gate else
6117c478bd9Sstevel@tonic-gate tabflg = 0;
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate /*
6157c478bd9Sstevel@tonic-gate * Print machine identification.
6167c478bd9Sstevel@tonic-gate */
6177c478bd9Sstevel@tonic-gate static void
prtmachid(void)6187c478bd9Sstevel@tonic-gate prtmachid(void)
6197c478bd9Sstevel@tonic-gate {
6207c478bd9Sstevel@tonic-gate struct utsname name;
6217c478bd9Sstevel@tonic-gate
6227c478bd9Sstevel@tonic-gate (void) uname(&name);
6237c478bd9Sstevel@tonic-gate (void) printf("\n%s %s %s %s %s %.2d/%.2d/%.4d\n",
6247c478bd9Sstevel@tonic-gate name.sysname, name.nodename, name.release, name.version,
6257c478bd9Sstevel@tonic-gate name.machine, curt->tm_mon + 1, curt->tm_mday,
6267c478bd9Sstevel@tonic-gate curt->tm_year + 1900);
6277c478bd9Sstevel@tonic-gate }
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate /*
6307c478bd9Sstevel@tonic-gate * Print report heading routine.
6317c478bd9Sstevel@tonic-gate */
6327c478bd9Sstevel@tonic-gate static void
prthdg(void)6337c478bd9Sstevel@tonic-gate prthdg(void)
6347c478bd9Sstevel@tonic-gate {
6357c478bd9Sstevel@tonic-gate int jj = 0;
6367c478bd9Sstevel@tonic-gate char ccc;
6377c478bd9Sstevel@tonic-gate
6387c478bd9Sstevel@tonic-gate (void) printf("\n");
6397c478bd9Sstevel@tonic-gate prttim();
6407c478bd9Sstevel@tonic-gate while ((ccc = fopt[jj++]) != NULL) {
6417c478bd9Sstevel@tonic-gate tsttab();
6427c478bd9Sstevel@tonic-gate switch (ccc) {
6437c478bd9Sstevel@tonic-gate case 'u':
6447c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s\n",
6457c478bd9Sstevel@tonic-gate "%usr",
6467c478bd9Sstevel@tonic-gate "%sys",
6477c478bd9Sstevel@tonic-gate "%wio",
6487c478bd9Sstevel@tonic-gate "%idle");
6497c478bd9Sstevel@tonic-gate break;
6507c478bd9Sstevel@tonic-gate case 'b':
6517c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s %7s %7s %7s %7s\n",
6527c478bd9Sstevel@tonic-gate "bread/s",
6537c478bd9Sstevel@tonic-gate "lread/s",
6547c478bd9Sstevel@tonic-gate "%rcache",
6557c478bd9Sstevel@tonic-gate "bwrit/s",
6567c478bd9Sstevel@tonic-gate "lwrit/s",
6577c478bd9Sstevel@tonic-gate "%wcache",
6587c478bd9Sstevel@tonic-gate "pread/s",
6597c478bd9Sstevel@tonic-gate "pwrit/s");
6607c478bd9Sstevel@tonic-gate break;
6617c478bd9Sstevel@tonic-gate case 'd':
6627c478bd9Sstevel@tonic-gate (void) printf(" %-8.8s %7s %7s %7s %7s %7s %7s\n",
6637c478bd9Sstevel@tonic-gate "device",
6647c478bd9Sstevel@tonic-gate "%busy",
6657c478bd9Sstevel@tonic-gate "avque",
6667c478bd9Sstevel@tonic-gate "r+w/s",
6677c478bd9Sstevel@tonic-gate "blks/s",
6687c478bd9Sstevel@tonic-gate "avwait",
6697c478bd9Sstevel@tonic-gate "avserv");
6707c478bd9Sstevel@tonic-gate break;
6717c478bd9Sstevel@tonic-gate case 'y':
6727c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s %7s %7s\n",
6737c478bd9Sstevel@tonic-gate "rawch/s",
6747c478bd9Sstevel@tonic-gate "canch/s",
6757c478bd9Sstevel@tonic-gate "outch/s",
6767c478bd9Sstevel@tonic-gate "rcvin/s",
6777c478bd9Sstevel@tonic-gate "xmtin/s",
6787c478bd9Sstevel@tonic-gate "mdmin/s");
6797c478bd9Sstevel@tonic-gate break;
6807c478bd9Sstevel@tonic-gate case 'c':
6817c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s %7s %7s %7s\n",
6827c478bd9Sstevel@tonic-gate "scall/s",
6837c478bd9Sstevel@tonic-gate "sread/s",
6847c478bd9Sstevel@tonic-gate "swrit/s",
6857c478bd9Sstevel@tonic-gate "fork/s",
6867c478bd9Sstevel@tonic-gate "exec/s",
6877c478bd9Sstevel@tonic-gate "rchar/s",
6887c478bd9Sstevel@tonic-gate "wchar/s");
6897c478bd9Sstevel@tonic-gate break;
6907c478bd9Sstevel@tonic-gate case 'w':
6917c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s %7s\n",
6927c478bd9Sstevel@tonic-gate "swpin/s",
6937c478bd9Sstevel@tonic-gate "bswin/s",
6947c478bd9Sstevel@tonic-gate "swpot/s",
6957c478bd9Sstevel@tonic-gate "bswot/s",
6967c478bd9Sstevel@tonic-gate "pswch/s");
6977c478bd9Sstevel@tonic-gate break;
6987c478bd9Sstevel@tonic-gate case 'a':
6997c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s\n",
7007c478bd9Sstevel@tonic-gate "iget/s",
7017c478bd9Sstevel@tonic-gate "namei/s",
7027c478bd9Sstevel@tonic-gate "dirbk/s");
7037c478bd9Sstevel@tonic-gate break;
7047c478bd9Sstevel@tonic-gate case 'q':
7057c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s\n",
7067c478bd9Sstevel@tonic-gate "runq-sz",
7077c478bd9Sstevel@tonic-gate "%runocc",
7087c478bd9Sstevel@tonic-gate "swpq-sz",
7097c478bd9Sstevel@tonic-gate "%swpocc");
7107c478bd9Sstevel@tonic-gate break;
7117c478bd9Sstevel@tonic-gate case 'v':
7127c478bd9Sstevel@tonic-gate (void) printf(" %s %s %s %s\n",
7137c478bd9Sstevel@tonic-gate "proc-sz ov",
7147c478bd9Sstevel@tonic-gate "inod-sz ov",
7157c478bd9Sstevel@tonic-gate "file-sz ov",
7167c478bd9Sstevel@tonic-gate "lock-sz");
7177c478bd9Sstevel@tonic-gate break;
7187c478bd9Sstevel@tonic-gate case 'm':
7197c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s\n",
7207c478bd9Sstevel@tonic-gate "msg/s",
7217c478bd9Sstevel@tonic-gate "sema/s");
7227c478bd9Sstevel@tonic-gate break;
7237c478bd9Sstevel@tonic-gate case 'p':
7247c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %7s %7s %7s %7s\n",
7257c478bd9Sstevel@tonic-gate "atch/s",
7267c478bd9Sstevel@tonic-gate "pgin/s",
7277c478bd9Sstevel@tonic-gate "ppgin/s",
7287c478bd9Sstevel@tonic-gate "pflt/s",
7297c478bd9Sstevel@tonic-gate "vflt/s",
7307c478bd9Sstevel@tonic-gate "slock/s");
7317c478bd9Sstevel@tonic-gate break;
7327c478bd9Sstevel@tonic-gate case 'g':
7337c478bd9Sstevel@tonic-gate (void) printf(" %8s %8s %8s %8s %8s\n",
7347c478bd9Sstevel@tonic-gate "pgout/s",
7357c478bd9Sstevel@tonic-gate "ppgout/s",
7367c478bd9Sstevel@tonic-gate "pgfree/s",
7377c478bd9Sstevel@tonic-gate "pgscan/s",
7387c478bd9Sstevel@tonic-gate "%ufs_ipf");
7397c478bd9Sstevel@tonic-gate break;
7407c478bd9Sstevel@tonic-gate case 'r':
7417c478bd9Sstevel@tonic-gate (void) printf(" %7s %8s\n",
7427c478bd9Sstevel@tonic-gate "freemem",
7437c478bd9Sstevel@tonic-gate "freeswap");
7447c478bd9Sstevel@tonic-gate break;
7457c478bd9Sstevel@tonic-gate case 'k':
7467c478bd9Sstevel@tonic-gate (void) printf(" %7s %7s %5s %7s %7s %5s %11s %5s\n",
7477c478bd9Sstevel@tonic-gate "sml_mem",
7487c478bd9Sstevel@tonic-gate "alloc",
7497c478bd9Sstevel@tonic-gate "fail",
7507c478bd9Sstevel@tonic-gate "lg_mem",
7517c478bd9Sstevel@tonic-gate "alloc",
7527c478bd9Sstevel@tonic-gate "fail",
7537c478bd9Sstevel@tonic-gate "ovsz_alloc",
7547c478bd9Sstevel@tonic-gate "fail");
7557c478bd9Sstevel@tonic-gate break;
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate }
7587c478bd9Sstevel@tonic-gate if (jj > 2 || do_disk)
7597c478bd9Sstevel@tonic-gate (void) printf("\n");
7607c478bd9Sstevel@tonic-gate }
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate /*
7637c478bd9Sstevel@tonic-gate * compute deltas and update accumulators
7647c478bd9Sstevel@tonic-gate */
7657c478bd9Sstevel@tonic-gate static void
update_counters(void)7667c478bd9Sstevel@tonic-gate update_counters(void)
7677c478bd9Sstevel@tonic-gate {
7687c478bd9Sstevel@tonic-gate int i;
7697c478bd9Sstevel@tonic-gate iodevinfo_t *nio, *oio, *aio, *dio;
7707c478bd9Sstevel@tonic-gate
771b9b602f4Sjs198686 ulong_delta((uint64_t *)&nx.csi, (uint64_t *)&ox.csi,
772b9b602f4Sjs198686 (uint64_t *)&dx.csi, (uint64_t *)&ax.csi, 0, sizeof (ax.csi));
773b9b602f4Sjs198686 ulong_delta((uint64_t *)&nx.si, (uint64_t *)&ox.si,
774b9b602f4Sjs198686 (uint64_t *)&dx.si, (uint64_t *)&ax.si, 0, sizeof (ax.si));
775b9b602f4Sjs198686 ulong_delta((uint64_t *)&nx.cvmi, (uint64_t *)&ox.cvmi,
776b9b602f4Sjs198686 (uint64_t *)&dx.cvmi, (uint64_t *)&ax.cvmi, 0,
7777c478bd9Sstevel@tonic-gate sizeof (ax.cvmi));
7787c478bd9Sstevel@tonic-gate
7797c478bd9Sstevel@tonic-gate ax.vmi.freemem += dx.vmi.freemem = nx.vmi.freemem - ox.vmi.freemem;
7807c478bd9Sstevel@tonic-gate ax.vmi.swap_avail += dx.vmi.swap_avail =
7817c478bd9Sstevel@tonic-gate nx.vmi.swap_avail - ox.vmi.swap_avail;
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate nio = nxio;
7847c478bd9Sstevel@tonic-gate oio = oxio;
7857c478bd9Sstevel@tonic-gate aio = axio;
7867c478bd9Sstevel@tonic-gate dio = dxio;
7877c478bd9Sstevel@tonic-gate for (i = 0; i < niodevs; i++) {
7887c478bd9Sstevel@tonic-gate aio->kios.wlastupdate += dio->kios.wlastupdate
7897c478bd9Sstevel@tonic-gate = nio->kios.wlastupdate - oio->kios.wlastupdate;
7907c478bd9Sstevel@tonic-gate aio->kios.reads += dio->kios.reads
7917c478bd9Sstevel@tonic-gate = nio->kios.reads - oio->kios.reads;
7927c478bd9Sstevel@tonic-gate aio->kios.writes += dio->kios.writes
7937c478bd9Sstevel@tonic-gate = nio->kios.writes - oio->kios.writes;
7947c478bd9Sstevel@tonic-gate aio->kios.nread += dio->kios.nread
7957c478bd9Sstevel@tonic-gate = nio->kios.nread - oio->kios.nread;
7967c478bd9Sstevel@tonic-gate aio->kios.nwritten += dio->kios.nwritten
7977c478bd9Sstevel@tonic-gate = nio->kios.nwritten - oio->kios.nwritten;
7987c478bd9Sstevel@tonic-gate aio->kios.wlentime += dio->kios.wlentime
7997c478bd9Sstevel@tonic-gate = nio->kios.wlentime - oio->kios.wlentime;
8007c478bd9Sstevel@tonic-gate aio->kios.rlentime += dio->kios.rlentime
8017c478bd9Sstevel@tonic-gate = nio->kios.rlentime - oio->kios.rlentime;
8027c478bd9Sstevel@tonic-gate aio->kios.wtime += dio->kios.wtime
8037c478bd9Sstevel@tonic-gate = nio->kios.wtime - oio->kios.wtime;
8047c478bd9Sstevel@tonic-gate aio->kios.rtime += dio->kios.rtime
8057c478bd9Sstevel@tonic-gate = nio->kios.rtime - oio->kios.rtime;
806*f83fba1aSGowtham Thommandra aio->ks.ks_snaptime += dio->ks.ks_snaptime
807*f83fba1aSGowtham Thommandra = nio->ks.ks_snaptime - oio->ks.ks_snaptime;
8087c478bd9Sstevel@tonic-gate nio++;
8097c478bd9Sstevel@tonic-gate oio++;
8107c478bd9Sstevel@tonic-gate aio++;
8117c478bd9Sstevel@tonic-gate dio++;
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate }
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate static void
prt_u_opt(struct sa64 * xx)816b9b602f4Sjs198686 prt_u_opt(struct sa64 *xx)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %7.0f %7.0f\n",
8197c478bd9Sstevel@tonic-gate (float)xx->csi.cpu[1] * percent,
8207c478bd9Sstevel@tonic-gate (float)xx->csi.cpu[2] * percent,
8217c478bd9Sstevel@tonic-gate (float)xx->csi.cpu[3] * percent,
8227c478bd9Sstevel@tonic-gate (float)xx->csi.cpu[0] * percent);
8237c478bd9Sstevel@tonic-gate }
8247c478bd9Sstevel@tonic-gate
8257c478bd9Sstevel@tonic-gate static void
prt_b_opt(struct sa64 * xx)826b9b602f4Sjs198686 prt_b_opt(struct sa64 *xx)
8277c478bd9Sstevel@tonic-gate {
8287c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
8297c478bd9Sstevel@tonic-gate (float)xx->csi.bread / sec_diff,
8307c478bd9Sstevel@tonic-gate (float)xx->csi.lread / sec_diff,
8317c478bd9Sstevel@tonic-gate freq((float)xx->csi.lread, (float)xx->csi.bread),
8327c478bd9Sstevel@tonic-gate (float)xx->csi.bwrite / sec_diff,
8337c478bd9Sstevel@tonic-gate (float)xx->csi.lwrite / sec_diff,
8347c478bd9Sstevel@tonic-gate freq((float)xx->csi.lwrite, (float)xx->csi.bwrite),
8357c478bd9Sstevel@tonic-gate (float)xx->csi.phread / sec_diff,
8367c478bd9Sstevel@tonic-gate (float)xx->csi.phwrite / sec_diff);
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate
8397c478bd9Sstevel@tonic-gate static void
prt_d_opt(int ii,iodevinfo_t * xio)8407c478bd9Sstevel@tonic-gate prt_d_opt(int ii, iodevinfo_t *xio)
8417c478bd9Sstevel@tonic-gate {
842*f83fba1aSGowtham Thommandra double etime, hr_etime, tps, avq, avs, pbusy;
8437c478bd9Sstevel@tonic-gate
8447c478bd9Sstevel@tonic-gate tsttab();
8457c478bd9Sstevel@tonic-gate
846*f83fba1aSGowtham Thommandra hr_etime = (double)xio[ii].ks.ks_snaptime;
8477c478bd9Sstevel@tonic-gate if (hr_etime == 0.0)
8487c478bd9Sstevel@tonic-gate hr_etime = (double)NANOSEC;
849*f83fba1aSGowtham Thommandra pbusy = (double)xio[ii].kios.rtime * 100.0 / hr_etime;
850*f83fba1aSGowtham Thommandra if (pbusy > 100.0)
851*f83fba1aSGowtham Thommandra pbusy = 100.0;
8527c478bd9Sstevel@tonic-gate etime = hr_etime / (double)NANOSEC;
8537c478bd9Sstevel@tonic-gate tps = (double)(xio[ii].kios.reads + xio[ii].kios.writes) / etime;
8547c478bd9Sstevel@tonic-gate avq = (double)xio[ii].kios.wlentime / hr_etime;
8557c478bd9Sstevel@tonic-gate avs = (double)xio[ii].kios.rlentime / hr_etime;
8567c478bd9Sstevel@tonic-gate
8577c478bd9Sstevel@tonic-gate (void) printf(" %-8.8s ", nxio[ii].ks.ks_name);
8587c478bd9Sstevel@tonic-gate (void) printf("%7.0f %7.1f %7.0f %7.0f %7.1f %7.1f\n",
859*f83fba1aSGowtham Thommandra pbusy,
8607c478bd9Sstevel@tonic-gate avq + avs,
8617c478bd9Sstevel@tonic-gate tps,
8627c478bd9Sstevel@tonic-gate BLKS(xio[ii].kios.nread + xio[ii].kios.nwritten) / etime,
8637c478bd9Sstevel@tonic-gate (tps > 0 ? avq / tps * 1000.0 : 0.0),
8647c478bd9Sstevel@tonic-gate (tps > 0 ? avs / tps * 1000.0 : 0.0));
8657c478bd9Sstevel@tonic-gate }
8667c478bd9Sstevel@tonic-gate
8677c478bd9Sstevel@tonic-gate static void
prt_y_opt(struct sa64 * xx)868b9b602f4Sjs198686 prt_y_opt(struct sa64 *xx)
8697c478bd9Sstevel@tonic-gate {
8707c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
8717c478bd9Sstevel@tonic-gate (float)xx->csi.rawch / sec_diff,
8727c478bd9Sstevel@tonic-gate (float)xx->csi.canch / sec_diff,
8737c478bd9Sstevel@tonic-gate (float)xx->csi.outch / sec_diff,
8747c478bd9Sstevel@tonic-gate (float)xx->csi.rcvint / sec_diff,
8757c478bd9Sstevel@tonic-gate (float)xx->csi.xmtint / sec_diff,
8767c478bd9Sstevel@tonic-gate (float)xx->csi.mdmint / sec_diff);
8777c478bd9Sstevel@tonic-gate }
8787c478bd9Sstevel@tonic-gate
8797c478bd9Sstevel@tonic-gate static void
prt_c_opt(struct sa64 * xx)880b9b602f4Sjs198686 prt_c_opt(struct sa64 *xx)
8817c478bd9Sstevel@tonic-gate {
8827c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %7.0f %7.2f %7.2f %7.0f %7.0f\n",
8837c478bd9Sstevel@tonic-gate (float)xx->csi.syscall / sec_diff,
8847c478bd9Sstevel@tonic-gate (float)xx->csi.sysread / sec_diff,
8857c478bd9Sstevel@tonic-gate (float)xx->csi.syswrite / sec_diff,
8867c478bd9Sstevel@tonic-gate (float)(xx->csi.sysfork + xx->csi.sysvfork) / sec_diff,
8877c478bd9Sstevel@tonic-gate (float)xx->csi.sysexec / sec_diff,
8887c478bd9Sstevel@tonic-gate (float)xx->csi.readch / sec_diff,
8897c478bd9Sstevel@tonic-gate (float)xx->csi.writech / sec_diff);
8907c478bd9Sstevel@tonic-gate }
8917c478bd9Sstevel@tonic-gate
8927c478bd9Sstevel@tonic-gate static void
prt_w_opt(struct sa64 * xx)893b9b602f4Sjs198686 prt_w_opt(struct sa64 *xx)
8947c478bd9Sstevel@tonic-gate {
8957c478bd9Sstevel@tonic-gate (void) printf(" %7.2f %7.1f %7.2f %7.1f %7.0f\n",
8967c478bd9Sstevel@tonic-gate (float)xx->cvmi.swapin / sec_diff,
8977c478bd9Sstevel@tonic-gate (float)PGTOBLK(xx->cvmi.pgswapin) / sec_diff,
8987c478bd9Sstevel@tonic-gate (float)xx->cvmi.swapout / sec_diff,
8997c478bd9Sstevel@tonic-gate (float)PGTOBLK(xx->cvmi.pgswapout) / sec_diff,
9007c478bd9Sstevel@tonic-gate (float)xx->csi.pswitch / sec_diff);
9017c478bd9Sstevel@tonic-gate }
9027c478bd9Sstevel@tonic-gate
9037c478bd9Sstevel@tonic-gate static void
prt_a_opt(struct sa64 * xx)904b9b602f4Sjs198686 prt_a_opt(struct sa64 *xx)
9057c478bd9Sstevel@tonic-gate {
9067c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %7.0f\n",
9077c478bd9Sstevel@tonic-gate (float)xx->csi.ufsiget / sec_diff,
9087c478bd9Sstevel@tonic-gate (float)xx->csi.namei / sec_diff,
9097c478bd9Sstevel@tonic-gate (float)xx->csi.ufsdirblk / sec_diff);
9107c478bd9Sstevel@tonic-gate }
9117c478bd9Sstevel@tonic-gate
9127c478bd9Sstevel@tonic-gate static void
prt_q_opt(struct sa64 * xx)913b9b602f4Sjs198686 prt_q_opt(struct sa64 *xx)
9147c478bd9Sstevel@tonic-gate {
915b2d230ebSjc144527 if (xx->si.runocc == 0 || xx->si.updates == 0)
9167c478bd9Sstevel@tonic-gate (void) printf(" %7.1f %7.0f", 0., 0.);
9177c478bd9Sstevel@tonic-gate else {
9187c478bd9Sstevel@tonic-gate (void) printf(" %7.1f %7.0f",
9197c478bd9Sstevel@tonic-gate (float)xx->si.runque / (float)xx->si.runocc,
920b2d230ebSjc144527 (float)xx->si.runocc / (float)xx->si.updates * 100.0);
9217c478bd9Sstevel@tonic-gate }
922b2d230ebSjc144527 if (xx->si.swpocc == 0 || xx->si.updates == 0)
9237c478bd9Sstevel@tonic-gate (void) printf(" %7.1f %7.0f\n", 0., 0.);
9247c478bd9Sstevel@tonic-gate else {
9257c478bd9Sstevel@tonic-gate (void) printf(" %7.1f %7.0f\n",
9267c478bd9Sstevel@tonic-gate (float)xx->si.swpque / (float)xx->si.swpocc,
927b2d230ebSjc144527 (float)xx->si.swpocc / (float)xx->si.updates * 100.0);
9287c478bd9Sstevel@tonic-gate }
9297c478bd9Sstevel@tonic-gate }
9307c478bd9Sstevel@tonic-gate
9317c478bd9Sstevel@tonic-gate static void
prt_v_opt(struct sa64 * xx)932b9b602f4Sjs198686 prt_v_opt(struct sa64 *xx)
9337c478bd9Sstevel@tonic-gate {
934b9b602f4Sjs198686 (void) printf(" %4lu/%-4lu %4llu %4lu/%-4lu %4llu %4lu/%-4lu "
935b9b602f4Sjs198686 "%4llu %4lu/%-4lu\n",
9367c478bd9Sstevel@tonic-gate nx.szproc, nx.mszproc, xx->csi.procovf,
9377c478bd9Sstevel@tonic-gate nx.szinode, nx.mszinode, xx->csi.inodeovf,
9387c478bd9Sstevel@tonic-gate nx.szfile, nx.mszfile, xx->csi.fileovf,
9397c478bd9Sstevel@tonic-gate nx.szlckr, nx.mszlckr);
9407c478bd9Sstevel@tonic-gate }
9417c478bd9Sstevel@tonic-gate
9427c478bd9Sstevel@tonic-gate static void
prt_m_opt(struct sa64 * xx)943b9b602f4Sjs198686 prt_m_opt(struct sa64 *xx)
9447c478bd9Sstevel@tonic-gate {
9457c478bd9Sstevel@tonic-gate (void) printf(" %7.2f %7.2f\n",
9467c478bd9Sstevel@tonic-gate (float)xx->csi.msg / sec_diff,
9477c478bd9Sstevel@tonic-gate (float)xx->csi.sema / sec_diff);
9487c478bd9Sstevel@tonic-gate }
9497c478bd9Sstevel@tonic-gate
9507c478bd9Sstevel@tonic-gate static void
prt_p_opt(struct sa64 * xx)951b9b602f4Sjs198686 prt_p_opt(struct sa64 *xx)
9527c478bd9Sstevel@tonic-gate {
9537c478bd9Sstevel@tonic-gate (void) printf(" %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n",
9547c478bd9Sstevel@tonic-gate (float)xx->cvmi.pgfrec / sec_diff,
9557c478bd9Sstevel@tonic-gate (float)xx->cvmi.pgin / sec_diff,
9567c478bd9Sstevel@tonic-gate (float)xx->cvmi.pgpgin / sec_diff,
9577c478bd9Sstevel@tonic-gate (float)(xx->cvmi.prot_fault + xx->cvmi.cow_fault) / sec_diff,
9587c478bd9Sstevel@tonic-gate (float)(xx->cvmi.hat_fault + xx->cvmi.as_fault) / sec_diff,
9597c478bd9Sstevel@tonic-gate (float)xx->cvmi.softlock / sec_diff);
9607c478bd9Sstevel@tonic-gate }
9617c478bd9Sstevel@tonic-gate
9627c478bd9Sstevel@tonic-gate static void
prt_g_opt(struct sa64 * xx)963b9b602f4Sjs198686 prt_g_opt(struct sa64 *xx)
9647c478bd9Sstevel@tonic-gate {
9657c478bd9Sstevel@tonic-gate (void) printf(" %8.2f %8.2f %8.2f %8.2f %8.2f\n",
9667c478bd9Sstevel@tonic-gate (float)xx->cvmi.pgout / sec_diff,
9677c478bd9Sstevel@tonic-gate (float)xx->cvmi.pgpgout / sec_diff,
9687c478bd9Sstevel@tonic-gate (float)xx->cvmi.dfree / sec_diff,
9697c478bd9Sstevel@tonic-gate (float)xx->cvmi.scan / sec_diff,
9707c478bd9Sstevel@tonic-gate (float)xx->csi.ufsipage * 100.0 /
9717c478bd9Sstevel@tonic-gate denom((float)xx->csi.ufsipage +
9727c478bd9Sstevel@tonic-gate (float)xx->csi.ufsinopage));
9737c478bd9Sstevel@tonic-gate }
9747c478bd9Sstevel@tonic-gate
9757c478bd9Sstevel@tonic-gate static void
prt_r_opt(struct sa64 * xx)976b9b602f4Sjs198686 prt_r_opt(struct sa64 *xx)
9777c478bd9Sstevel@tonic-gate {
978b2d230ebSjc144527 /* Avoid divide by Zero - Should never happen */
979b2d230ebSjc144527 if (xx->si.updates == 0)
980b2d230ebSjc144527 (void) printf(" %7.0f %8.0f\n", 0., 0.);
981b2d230ebSjc144527 else {
9827c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %8.0f\n",
983b2d230ebSjc144527 (double)xx->vmi.freemem / (float)xx->si.updates,
984b2d230ebSjc144527 (double)PGTOBLK(xx->vmi.swap_avail) /
985b2d230ebSjc144527 (float)xx->si.updates);
986b2d230ebSjc144527 }
9877c478bd9Sstevel@tonic-gate }
9887c478bd9Sstevel@tonic-gate
9897c478bd9Sstevel@tonic-gate static void
prt_k_opt(struct sa64 * xx,int n)990b9b602f4Sjs198686 prt_k_opt(struct sa64 *xx, int n)
9917c478bd9Sstevel@tonic-gate {
9927c478bd9Sstevel@tonic-gate if (n != 1) {
9937c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %5.0f %7.0f %7.0f %5.0f %11.0f"
9947c478bd9Sstevel@tonic-gate " %5.0f\n",
9957c478bd9Sstevel@tonic-gate (float)kmi.km_mem[KMEM_SMALL] / n,
9967c478bd9Sstevel@tonic-gate (float)kmi.km_alloc[KMEM_SMALL] / n,
9977c478bd9Sstevel@tonic-gate (float)kmi.km_fail[KMEM_SMALL] / n,
9987c478bd9Sstevel@tonic-gate (float)kmi.km_mem[KMEM_LARGE] / n,
9997c478bd9Sstevel@tonic-gate (float)kmi.km_alloc[KMEM_LARGE] / n,
10007c478bd9Sstevel@tonic-gate (float)kmi.km_fail[KMEM_LARGE] / n,
10017c478bd9Sstevel@tonic-gate (float)kmi.km_alloc[KMEM_OSIZE] / n,
10027c478bd9Sstevel@tonic-gate (float)kmi.km_fail[KMEM_OSIZE] / n);
10037c478bd9Sstevel@tonic-gate } else {
10047c478bd9Sstevel@tonic-gate /*
10057c478bd9Sstevel@tonic-gate * If we are not reporting averages, use the read values
10067c478bd9Sstevel@tonic-gate * directly.
10077c478bd9Sstevel@tonic-gate */
10087c478bd9Sstevel@tonic-gate (void) printf(" %7.0f %7.0f %5.0f %7.0f %7.0f %5.0f %11.0f"
10097c478bd9Sstevel@tonic-gate " %5.0f\n",
10107c478bd9Sstevel@tonic-gate (float)xx->kmi.km_mem[KMEM_SMALL],
10117c478bd9Sstevel@tonic-gate (float)xx->kmi.km_alloc[KMEM_SMALL],
10127c478bd9Sstevel@tonic-gate (float)xx->kmi.km_fail[KMEM_SMALL],
10137c478bd9Sstevel@tonic-gate (float)xx->kmi.km_mem[KMEM_LARGE],
10147c478bd9Sstevel@tonic-gate (float)xx->kmi.km_alloc[KMEM_LARGE],
10157c478bd9Sstevel@tonic-gate (float)xx->kmi.km_fail[KMEM_LARGE],
10167c478bd9Sstevel@tonic-gate (float)xx->kmi.km_alloc[KMEM_OSIZE],
10177c478bd9Sstevel@tonic-gate (float)xx->kmi.km_fail[KMEM_OSIZE]);
10187c478bd9Sstevel@tonic-gate }
10197c478bd9Sstevel@tonic-gate }
10207c478bd9Sstevel@tonic-gate
10217c478bd9Sstevel@tonic-gate /*
10227c478bd9Sstevel@tonic-gate * Print options routine.
10237c478bd9Sstevel@tonic-gate */
10247c478bd9Sstevel@tonic-gate static void
prtopt(void)10257c478bd9Sstevel@tonic-gate prtopt(void)
10267c478bd9Sstevel@tonic-gate {
10277c478bd9Sstevel@tonic-gate int ii, jj = 0;
10287c478bd9Sstevel@tonic-gate char ccc;
10297c478bd9Sstevel@tonic-gate
10307c478bd9Sstevel@tonic-gate prttim();
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate while ((ccc = fopt[jj++]) != NULL) {
10337c478bd9Sstevel@tonic-gate if (ccc != 'd')
10347c478bd9Sstevel@tonic-gate tsttab();
10357c478bd9Sstevel@tonic-gate switch (ccc) {
10367c478bd9Sstevel@tonic-gate case 'u':
10377c478bd9Sstevel@tonic-gate prt_u_opt(&dx);
10387c478bd9Sstevel@tonic-gate break;
10397c478bd9Sstevel@tonic-gate case 'b':
10407c478bd9Sstevel@tonic-gate prt_b_opt(&dx);
10417c478bd9Sstevel@tonic-gate break;
10427c478bd9Sstevel@tonic-gate case 'd':
10437c478bd9Sstevel@tonic-gate for (ii = 0; ii < niodevs; ii++)
10447c478bd9Sstevel@tonic-gate prt_d_opt(ii, dxio);
10457c478bd9Sstevel@tonic-gate break;
10467c478bd9Sstevel@tonic-gate case 'y':
10477c478bd9Sstevel@tonic-gate prt_y_opt(&dx);
10487c478bd9Sstevel@tonic-gate break;
10497c478bd9Sstevel@tonic-gate case 'c':
10507c478bd9Sstevel@tonic-gate prt_c_opt(&dx);
10517c478bd9Sstevel@tonic-gate break;
10527c478bd9Sstevel@tonic-gate case 'w':
10537c478bd9Sstevel@tonic-gate prt_w_opt(&dx);
10547c478bd9Sstevel@tonic-gate break;
10557c478bd9Sstevel@tonic-gate case 'a':
10567c478bd9Sstevel@tonic-gate prt_a_opt(&dx);
10577c478bd9Sstevel@tonic-gate break;
10587c478bd9Sstevel@tonic-gate case 'q':
10597c478bd9Sstevel@tonic-gate prt_q_opt(&dx);
10607c478bd9Sstevel@tonic-gate break;
10617c478bd9Sstevel@tonic-gate case 'v':
10627c478bd9Sstevel@tonic-gate prt_v_opt(&dx);
10637c478bd9Sstevel@tonic-gate break;
10647c478bd9Sstevel@tonic-gate case 'm':
10657c478bd9Sstevel@tonic-gate prt_m_opt(&dx);
10667c478bd9Sstevel@tonic-gate break;
10677c478bd9Sstevel@tonic-gate case 'p':
10687c478bd9Sstevel@tonic-gate prt_p_opt(&dx);
10697c478bd9Sstevel@tonic-gate break;
10707c478bd9Sstevel@tonic-gate case 'g':
10717c478bd9Sstevel@tonic-gate prt_g_opt(&dx);
10727c478bd9Sstevel@tonic-gate break;
10737c478bd9Sstevel@tonic-gate case 'r':
10747c478bd9Sstevel@tonic-gate prt_r_opt(&dx);
10757c478bd9Sstevel@tonic-gate break;
10767c478bd9Sstevel@tonic-gate case 'k':
10777c478bd9Sstevel@tonic-gate prt_k_opt(&nx, 1);
10787c478bd9Sstevel@tonic-gate /*
10797c478bd9Sstevel@tonic-gate * To avoid overflow, copy the data from the sa record
10807c478bd9Sstevel@tonic-gate * into a struct kmeminfo_l which has members with
10817c478bd9Sstevel@tonic-gate * larger data types.
10827c478bd9Sstevel@tonic-gate */
10837c478bd9Sstevel@tonic-gate kmi.km_mem[KMEM_SMALL] += nx.kmi.km_mem[KMEM_SMALL];
10847c478bd9Sstevel@tonic-gate kmi.km_alloc[KMEM_SMALL] += nx.kmi.km_alloc[KMEM_SMALL];
10857c478bd9Sstevel@tonic-gate kmi.km_fail[KMEM_SMALL] += nx.kmi.km_fail[KMEM_SMALL];
10867c478bd9Sstevel@tonic-gate kmi.km_mem[KMEM_LARGE] += nx.kmi.km_mem[KMEM_LARGE];
10877c478bd9Sstevel@tonic-gate kmi.km_alloc[KMEM_LARGE] += nx.kmi.km_alloc[KMEM_LARGE];
10887c478bd9Sstevel@tonic-gate kmi.km_fail[KMEM_LARGE] += nx.kmi.km_fail[KMEM_LARGE];
10897c478bd9Sstevel@tonic-gate kmi.km_alloc[KMEM_OSIZE] += nx.kmi.km_alloc[KMEM_OSIZE];
10907c478bd9Sstevel@tonic-gate kmi.km_fail[KMEM_OSIZE] += nx.kmi.km_fail[KMEM_OSIZE];
10917c478bd9Sstevel@tonic-gate break;
10927c478bd9Sstevel@tonic-gate }
10937c478bd9Sstevel@tonic-gate }
10947c478bd9Sstevel@tonic-gate if (jj > 2 || do_disk)
10957c478bd9Sstevel@tonic-gate (void) printf("\n");
10967c478bd9Sstevel@tonic-gate if (realtime)
10977c478bd9Sstevel@tonic-gate (void) fflush(stdout);
10987c478bd9Sstevel@tonic-gate }
10997c478bd9Sstevel@tonic-gate
11007c478bd9Sstevel@tonic-gate /*
11017c478bd9Sstevel@tonic-gate * Print average routine.
11027c478bd9Sstevel@tonic-gate */
11037c478bd9Sstevel@tonic-gate static void
prtavg(void)11047c478bd9Sstevel@tonic-gate prtavg(void)
11057c478bd9Sstevel@tonic-gate {
11067c478bd9Sstevel@tonic-gate int ii, jj = 0;
11077c478bd9Sstevel@tonic-gate char ccc;
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate tdiff = ax.csi.cpu[0] + ax.csi.cpu[1] + ax.csi.cpu[2] + ax.csi.cpu[3];
11107c478bd9Sstevel@tonic-gate if (tdiff <= 0.0)
11117c478bd9Sstevel@tonic-gate return;
11127c478bd9Sstevel@tonic-gate
11137c478bd9Sstevel@tonic-gate sec_diff = tdiff / hz;
11147c478bd9Sstevel@tonic-gate percent = 100.0 / tdiff;
11157c478bd9Sstevel@tonic-gate (void) printf("\n");
11167c478bd9Sstevel@tonic-gate
11177c478bd9Sstevel@tonic-gate while ((ccc = fopt[jj++]) != NULL) {
11187c478bd9Sstevel@tonic-gate if (ccc != 'v')
11197c478bd9Sstevel@tonic-gate (void) printf("Average ");
11207c478bd9Sstevel@tonic-gate switch (ccc) {
11217c478bd9Sstevel@tonic-gate case 'u':
11227c478bd9Sstevel@tonic-gate prt_u_opt(&ax);
11237c478bd9Sstevel@tonic-gate break;
11247c478bd9Sstevel@tonic-gate case 'b':
11257c478bd9Sstevel@tonic-gate prt_b_opt(&ax);
11267c478bd9Sstevel@tonic-gate break;
11277c478bd9Sstevel@tonic-gate case 'd':
11287c478bd9Sstevel@tonic-gate tabflg = 1;
11297c478bd9Sstevel@tonic-gate for (ii = 0; ii < niodevs; ii++)
11307c478bd9Sstevel@tonic-gate prt_d_opt(ii, axio);
11317c478bd9Sstevel@tonic-gate break;
11327c478bd9Sstevel@tonic-gate case 'y':
11337c478bd9Sstevel@tonic-gate prt_y_opt(&ax);
11347c478bd9Sstevel@tonic-gate break;
11357c478bd9Sstevel@tonic-gate case 'c':
11367c478bd9Sstevel@tonic-gate prt_c_opt(&ax);
11377c478bd9Sstevel@tonic-gate break;
11387c478bd9Sstevel@tonic-gate case 'w':
11397c478bd9Sstevel@tonic-gate prt_w_opt(&ax);
11407c478bd9Sstevel@tonic-gate break;
11417c478bd9Sstevel@tonic-gate case 'a':
11427c478bd9Sstevel@tonic-gate prt_a_opt(&ax);
11437c478bd9Sstevel@tonic-gate break;
11447c478bd9Sstevel@tonic-gate case 'q':
11457c478bd9Sstevel@tonic-gate prt_q_opt(&ax);
11467c478bd9Sstevel@tonic-gate break;
11477c478bd9Sstevel@tonic-gate case 'v':
11487c478bd9Sstevel@tonic-gate break;
11497c478bd9Sstevel@tonic-gate case 'm':
11507c478bd9Sstevel@tonic-gate prt_m_opt(&ax);
11517c478bd9Sstevel@tonic-gate break;
11527c478bd9Sstevel@tonic-gate case 'p':
11537c478bd9Sstevel@tonic-gate prt_p_opt(&ax);
11547c478bd9Sstevel@tonic-gate break;
11557c478bd9Sstevel@tonic-gate case 'g':
11567c478bd9Sstevel@tonic-gate prt_g_opt(&ax);
11577c478bd9Sstevel@tonic-gate break;
11587c478bd9Sstevel@tonic-gate case 'r':
11597c478bd9Sstevel@tonic-gate prt_r_opt(&ax);
11607c478bd9Sstevel@tonic-gate break;
11617c478bd9Sstevel@tonic-gate case 'k':
11627c478bd9Sstevel@tonic-gate prt_k_opt(&ax, lines);
11637c478bd9Sstevel@tonic-gate break;
11647c478bd9Sstevel@tonic-gate }
11657c478bd9Sstevel@tonic-gate }
11667c478bd9Sstevel@tonic-gate }
11677c478bd9Sstevel@tonic-gate
11687c478bd9Sstevel@tonic-gate static void
ulong_delta(uint64_t * new,uint64_t * old,uint64_t * delta,uint64_t * accum,int begin,int end)1169b9b602f4Sjs198686 ulong_delta(uint64_t *new, uint64_t *old, uint64_t *delta, uint64_t *accum,
11707c478bd9Sstevel@tonic-gate int begin, int end)
11717c478bd9Sstevel@tonic-gate {
11727c478bd9Sstevel@tonic-gate int i;
1173b9b602f4Sjs198686 uint64_t n, o, d;
11747c478bd9Sstevel@tonic-gate
1175b9b602f4Sjs198686 for (i = begin; i < end; i += sizeof (uint64_t)) {
1176b9b602f4Sjs198686 n = *new++;
1177b9b602f4Sjs198686 o = *old++;
1178b9b602f4Sjs198686 if (o > n) {
1179b9b602f4Sjs198686 d = n + 0x100000000LL - o;
1180b9b602f4Sjs198686 } else {
1181b9b602f4Sjs198686 d = n - o;
1182b9b602f4Sjs198686 }
1183b9b602f4Sjs198686 *accum++ += *delta++ = d;
1184b9b602f4Sjs198686 }
11857c478bd9Sstevel@tonic-gate }
11867c478bd9Sstevel@tonic-gate
11877c478bd9Sstevel@tonic-gate /*
11887c478bd9Sstevel@tonic-gate * used to prevent zero denominators
11897c478bd9Sstevel@tonic-gate */
11907c478bd9Sstevel@tonic-gate static float
denom(float x)11917c478bd9Sstevel@tonic-gate denom(float x)
11927c478bd9Sstevel@tonic-gate {
11937c478bd9Sstevel@tonic-gate return ((x > 0.5) ? x : 1.0);
11947c478bd9Sstevel@tonic-gate }
11957c478bd9Sstevel@tonic-gate
11967c478bd9Sstevel@tonic-gate /*
11977c478bd9Sstevel@tonic-gate * a little calculation that comes up often when computing frequency
11987c478bd9Sstevel@tonic-gate * of one operation relative to another
11997c478bd9Sstevel@tonic-gate */
12007c478bd9Sstevel@tonic-gate static float
freq(float x,float y)12017c478bd9Sstevel@tonic-gate freq(float x, float y)
12027c478bd9Sstevel@tonic-gate {
12037c478bd9Sstevel@tonic-gate return ((x < 0.5) ? 100.0 : (x - y) / x * 100.0);
12047c478bd9Sstevel@tonic-gate }
12057c478bd9Sstevel@tonic-gate
12067c478bd9Sstevel@tonic-gate static void
usage(void)12077c478bd9Sstevel@tonic-gate usage(void)
12087c478bd9Sstevel@tonic-gate {
12097c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
12107c478bd9Sstevel@tonic-gate "usage: sar [-ubdycwaqvmpgrkA][-o file] t [n]\n"
12117c478bd9Sstevel@tonic-gate "\tsar [-ubdycwaqvmpgrkA] [-s hh:mm][-e hh:mm][-i ss][-f file]\n");
12127c478bd9Sstevel@tonic-gate }
12137c478bd9Sstevel@tonic-gate
12147c478bd9Sstevel@tonic-gate static void
fail(int do_perror,char * message,...)12157c478bd9Sstevel@tonic-gate fail(int do_perror, char *message, ...)
12167c478bd9Sstevel@tonic-gate {
12177c478bd9Sstevel@tonic-gate va_list args;
12187c478bd9Sstevel@tonic-gate
12197c478bd9Sstevel@tonic-gate va_start(args, message);
12207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "sar: ");
12217c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, message, args);
12227c478bd9Sstevel@tonic-gate va_end(args);
12237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n");
12247c478bd9Sstevel@tonic-gate switch (do_perror) {
12257c478bd9Sstevel@tonic-gate case 0: /* usage message */
12267c478bd9Sstevel@tonic-gate usage();
12277c478bd9Sstevel@tonic-gate break;
12287c478bd9Sstevel@tonic-gate case 1: /* perror output */
12297c478bd9Sstevel@tonic-gate perror("");
12307c478bd9Sstevel@tonic-gate break;
12317c478bd9Sstevel@tonic-gate case 2: /* no further output */
12327c478bd9Sstevel@tonic-gate break;
12337c478bd9Sstevel@tonic-gate default: /* error */
12347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "unsupported failure mode\n");
12357c478bd9Sstevel@tonic-gate break;
12367c478bd9Sstevel@tonic-gate }
12377c478bd9Sstevel@tonic-gate exit(2);
12387c478bd9Sstevel@tonic-gate }
12397c478bd9Sstevel@tonic-gate
12407c478bd9Sstevel@tonic-gate static int
safe_strtoi(char const * val,char * errmsg)12417c478bd9Sstevel@tonic-gate safe_strtoi(char const *val, char *errmsg)
12427c478bd9Sstevel@tonic-gate {
12437c478bd9Sstevel@tonic-gate char *end;
12447c478bd9Sstevel@tonic-gate long tmp;
12457c478bd9Sstevel@tonic-gate
12467c478bd9Sstevel@tonic-gate errno = 0;
12477c478bd9Sstevel@tonic-gate tmp = strtol(val, &end, 10);
12487c478bd9Sstevel@tonic-gate if (*end != '\0' || errno)
12497c478bd9Sstevel@tonic-gate fail(0, "%s %s", errmsg, val);
12507c478bd9Sstevel@tonic-gate return ((int)tmp);
12517c478bd9Sstevel@tonic-gate }
12527c478bd9Sstevel@tonic-gate
12537c478bd9Sstevel@tonic-gate static void
safe_zalloc(void ** ptr,int size,int free_first)12547c478bd9Sstevel@tonic-gate safe_zalloc(void **ptr, int size, int free_first)
12557c478bd9Sstevel@tonic-gate {
12567c478bd9Sstevel@tonic-gate if (free_first && *ptr != NULL)
12577c478bd9Sstevel@tonic-gate free(*ptr);
12587c478bd9Sstevel@tonic-gate if ((*ptr = malloc(size)) == NULL)
12597c478bd9Sstevel@tonic-gate fail(1, "malloc failed");
12607c478bd9Sstevel@tonic-gate (void) memset(*ptr, 0, size);
12617c478bd9Sstevel@tonic-gate }
12627c478bd9Sstevel@tonic-gate
12637c478bd9Sstevel@tonic-gate static int
safe_read(int fd,void * buf,size_t size)12647c478bd9Sstevel@tonic-gate safe_read(int fd, void *buf, size_t size)
12657c478bd9Sstevel@tonic-gate {
12667c478bd9Sstevel@tonic-gate size_t rsize = read(fd, buf, size);
12677c478bd9Sstevel@tonic-gate
12687c478bd9Sstevel@tonic-gate if (rsize == 0)
12697c478bd9Sstevel@tonic-gate return (0);
12707c478bd9Sstevel@tonic-gate
12717c478bd9Sstevel@tonic-gate if (rsize != size)
12727c478bd9Sstevel@tonic-gate fail(1, "read failed");
12737c478bd9Sstevel@tonic-gate
12747c478bd9Sstevel@tonic-gate return (1);
12757c478bd9Sstevel@tonic-gate }
12767c478bd9Sstevel@tonic-gate
12777c478bd9Sstevel@tonic-gate static void
safe_write(int fd,void * buf,size_t size)12787c478bd9Sstevel@tonic-gate safe_write(int fd, void *buf, size_t size)
12797c478bd9Sstevel@tonic-gate {
12807c478bd9Sstevel@tonic-gate if (write(fd, buf, size) != size)
12817c478bd9Sstevel@tonic-gate fail(1, "write failed");
12827c478bd9Sstevel@tonic-gate }
1283