xref: /titanic_51/usr/src/cmd/rcap/rcapstat/rcapstat.c (revision 19449258028e6813f0b7a606b554b2fa37a390ec)
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
50209230bSgjelinek  * Common Development and Distribution License (the "License").
60209230bSgjelinek  * 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  */
2123a1cceaSRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
2323a1cceaSRoger A. Faulkner  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/stat.h>
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate #include <fcntl.h>
307c478bd9Sstevel@tonic-gate #include <errno.h>
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <strings.h>
357c478bd9Sstevel@tonic-gate #include <libintl.h>
367c478bd9Sstevel@tonic-gate #include <locale.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include "rcapd.h"
397c478bd9Sstevel@tonic-gate #include "utils.h"
407c478bd9Sstevel@tonic-gate #include "rcapd_stat.h"
4126fd7700SKrishnendu Sadhukhan - Sun Microsystems #include "statcommon.h"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate static char mode[RC_MODE_LEN];
447c478bd9Sstevel@tonic-gate static rcapd_stat_hdr_t hdr;
457c478bd9Sstevel@tonic-gate static int global;
467c478bd9Sstevel@tonic-gate static int unformatted;
477c478bd9Sstevel@tonic-gate static time_t stat_mod = 0;
487c478bd9Sstevel@tonic-gate 
4926fd7700SKrishnendu Sadhukhan - Sun Microsystems static uint_t timestamp_fmt = NODATE;
5026fd7700SKrishnendu Sadhukhan - Sun Microsystems 
517c478bd9Sstevel@tonic-gate typedef struct col {
527c478bd9Sstevel@tonic-gate 	rcid_t		col_id;
537c478bd9Sstevel@tonic-gate 	char		col_name[LC_NAME_LEN];
547c478bd9Sstevel@tonic-gate 	uint64_t	col_nproc;
557c478bd9Sstevel@tonic-gate 	uint64_t	col_vmsize;
567c478bd9Sstevel@tonic-gate 	uint64_t	col_rsssize;
577c478bd9Sstevel@tonic-gate 	uint64_t	col_rsslimit;
587c478bd9Sstevel@tonic-gate 	uint64_t	col_paged_eff;
597c478bd9Sstevel@tonic-gate 	uint64_t	col_paged_eff_old;
607c478bd9Sstevel@tonic-gate 	uint64_t	col_paged_eff_avg;
617c478bd9Sstevel@tonic-gate 	uint64_t	col_paged_att;
627c478bd9Sstevel@tonic-gate 	uint64_t	col_paged_att_old;
637c478bd9Sstevel@tonic-gate 	uint64_t	col_paged_att_avg;
647c478bd9Sstevel@tonic-gate 	uint64_t	col_count;
657c478bd9Sstevel@tonic-gate 	int		col_fresh;
667c478bd9Sstevel@tonic-gate 	struct col	*col_next;
677c478bd9Sstevel@tonic-gate 	struct col	*col_prev;
687c478bd9Sstevel@tonic-gate 	lcollection_stat_t	col_src_stat;
697c478bd9Sstevel@tonic-gate 	lcollection_stat_t	col_old_stat;
707c478bd9Sstevel@tonic-gate } col_t;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate static col_t *col_head;
737c478bd9Sstevel@tonic-gate static int ncol;
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate static col_t *
767c478bd9Sstevel@tonic-gate col_find(rcid_t id)
777c478bd9Sstevel@tonic-gate {
787c478bd9Sstevel@tonic-gate 	col_t *col;
797c478bd9Sstevel@tonic-gate 	for (col = col_head; col != NULL; col = col->col_next)
800209230bSgjelinek 		if (col->col_id.rcid_type == id.rcid_type &&
810209230bSgjelinek 		    col->col_id.rcid_val == id.rcid_val)
827c478bd9Sstevel@tonic-gate 			return (col);
837c478bd9Sstevel@tonic-gate 	return (NULL);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate static col_t *
877c478bd9Sstevel@tonic-gate col_insert(rcid_t id)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate 	col_t *new_col;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	new_col = malloc(sizeof (col_t));
927c478bd9Sstevel@tonic-gate 	if (new_col == NULL) {
937c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("rcapstat: malloc() failed\n"));
947c478bd9Sstevel@tonic-gate 		exit(E_ERROR);
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 	(void) memset(new_col, 0, sizeof (col_t));
977c478bd9Sstevel@tonic-gate 	new_col->col_next = col_head;
987c478bd9Sstevel@tonic-gate 	new_col->col_id = id;
997c478bd9Sstevel@tonic-gate 	if (col_head != NULL)
1007c478bd9Sstevel@tonic-gate 		col_head->col_prev = new_col;
1017c478bd9Sstevel@tonic-gate 	col_head = new_col;
1027c478bd9Sstevel@tonic-gate 	ncol++;
1037c478bd9Sstevel@tonic-gate 	return (new_col);
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate static void
1077c478bd9Sstevel@tonic-gate col_remove(col_t *col)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	if (col->col_prev != NULL)
1107c478bd9Sstevel@tonic-gate 		col->col_prev->col_next = col->col_next;
1117c478bd9Sstevel@tonic-gate 	if (col->col_next != NULL)
1127c478bd9Sstevel@tonic-gate 		col->col_next->col_prev = col->col_prev;
1137c478bd9Sstevel@tonic-gate 	if (col_head == col)
1147c478bd9Sstevel@tonic-gate 		col_head = col->col_next;
1157c478bd9Sstevel@tonic-gate 	ncol--;
1167c478bd9Sstevel@tonic-gate 	free(col);
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate static void
1207c478bd9Sstevel@tonic-gate usage()
1217c478bd9Sstevel@tonic-gate {
1227c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
12326fd7700SKrishnendu Sadhukhan - Sun Microsystems 	    gettext("usage: rcapstat [-g] [-p | -z] [-T d|u] "
12426fd7700SKrishnendu Sadhukhan - Sun Microsystems 	    "[interval [count]]\n"));
1257c478bd9Sstevel@tonic-gate 	exit(E_USAGE);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate static void
1297c478bd9Sstevel@tonic-gate format_size(char *str, uint64_t size, int length)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	char tag = 'K';
1327c478bd9Sstevel@tonic-gate 	if (size >= 10000) {
1337c478bd9Sstevel@tonic-gate 		size = (size + 512) / 1024;
1347c478bd9Sstevel@tonic-gate 		tag = 'M';
1357c478bd9Sstevel@tonic-gate 		if (size >= 10000) {
1367c478bd9Sstevel@tonic-gate 			size = (size + 512) / 1024;
1377c478bd9Sstevel@tonic-gate 			tag = 'G';
1387c478bd9Sstevel@tonic-gate 		}
1397c478bd9Sstevel@tonic-gate 	}
1407c478bd9Sstevel@tonic-gate 	(void) snprintf(str, length, "%4lld%c", size, tag);
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate static int
1440209230bSgjelinek read_stats(rcid_type_t stat_type)
1457c478bd9Sstevel@tonic-gate {
1467c478bd9Sstevel@tonic-gate 	int fd;
1477c478bd9Sstevel@tonic-gate 	int proc_fd;
1487c478bd9Sstevel@tonic-gate 	char procfile[20];
1490209230bSgjelinek 	uint64_t pid;
1507c478bd9Sstevel@tonic-gate 	col_t *col, *col_next;
1517c478bd9Sstevel@tonic-gate 	lcollection_report_t report;
1527c478bd9Sstevel@tonic-gate 	struct stat st;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	if ((fd = open(STAT_FILE_DEFAULT, O_RDONLY)) < 0) {
1557c478bd9Sstevel@tonic-gate 		warn(gettext("rcapd is not active\n"));
1567c478bd9Sstevel@tonic-gate 		return (E_ERROR);
1577c478bd9Sstevel@tonic-gate 	}
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	if (fstat(fd, &st) == 0)
1607c478bd9Sstevel@tonic-gate 		stat_mod = st.st_mtime;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	if (read(fd, &hdr, sizeof (hdr)) != sizeof (hdr)) {
1637c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
1647c478bd9Sstevel@tonic-gate 		    gettext("rcapstat: can't read stat file header: %s\n"),
1657c478bd9Sstevel@tonic-gate 		    strerror(errno));
1667c478bd9Sstevel@tonic-gate 		(void) close(fd);
1677c478bd9Sstevel@tonic-gate 		return (E_ERROR);
1687c478bd9Sstevel@tonic-gate 	}
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 	/*
1717c478bd9Sstevel@tonic-gate 	 * Check if rcapd is running
1727c478bd9Sstevel@tonic-gate 	 */
1737c478bd9Sstevel@tonic-gate 	pid = hdr.rs_pid;
1740209230bSgjelinek 	(void) snprintf(procfile, 20, "/proc/%lld/psinfo", pid);
1757c478bd9Sstevel@tonic-gate 	if ((proc_fd = open(procfile, O_RDONLY)) < 0) {
1767c478bd9Sstevel@tonic-gate 		warn(gettext("rcapd is not active\n"));
1777c478bd9Sstevel@tonic-gate 		(void) close(fd);
1787c478bd9Sstevel@tonic-gate 		return (E_ERROR);
1797c478bd9Sstevel@tonic-gate 	}
1807c478bd9Sstevel@tonic-gate 	(void) close(proc_fd);
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	(void) strncpy(mode, hdr.rs_mode, RC_MODE_LEN);
1837c478bd9Sstevel@tonic-gate 	for (col = col_head; col != NULL; col = col->col_next) {
1847c478bd9Sstevel@tonic-gate 		col->col_fresh = 0;
1857c478bd9Sstevel@tonic-gate 		col->col_paged_eff = 0;
1867c478bd9Sstevel@tonic-gate 		col->col_paged_att = 0;
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	while (read(fd, &report, sizeof (report)) == sizeof (report)) {
1900209230bSgjelinek 		if (report.lcol_id.rcid_type != stat_type)
1910209230bSgjelinek 			continue;
1920209230bSgjelinek 
1937c478bd9Sstevel@tonic-gate 		col = col_find(report.lcol_id);
1947c478bd9Sstevel@tonic-gate 		if (col == NULL) {
1957c478bd9Sstevel@tonic-gate 			col = col_insert(report.lcol_id);
1967c478bd9Sstevel@tonic-gate 			col->col_paged_eff_old = col->col_paged_eff =
1977c478bd9Sstevel@tonic-gate 			    report.lcol_stat.lcols_pg_eff;
1987c478bd9Sstevel@tonic-gate 			col->col_paged_att_old = col->col_paged_att =
1997c478bd9Sstevel@tonic-gate 			    report.lcol_stat.lcols_pg_att;
2007c478bd9Sstevel@tonic-gate 			col->col_count = 0;
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate 		(void) strncpy(col->col_name, report.lcol_name, LC_NAME_LEN);
2037c478bd9Sstevel@tonic-gate 		col->col_vmsize = report.lcol_image_size;
2047c478bd9Sstevel@tonic-gate 		col->col_rsssize = report.lcol_rss;
2057c478bd9Sstevel@tonic-gate 		col->col_rsslimit = report.lcol_rss_cap;
2067c478bd9Sstevel@tonic-gate 		col->col_fresh = 1;
2077c478bd9Sstevel@tonic-gate 		if (report.lcol_stat.lcols_pg_eff > col->col_paged_eff_old) {
2087c478bd9Sstevel@tonic-gate 			col->col_paged_eff =
2097c478bd9Sstevel@tonic-gate 			    report.lcol_stat.lcols_pg_eff -
2107c478bd9Sstevel@tonic-gate 			    col->col_paged_eff_old;
2117c478bd9Sstevel@tonic-gate 			if (report.lcol_stat.lcols_scan_count > col->col_count)
2127c478bd9Sstevel@tonic-gate 				col->col_paged_eff_avg =
2137c478bd9Sstevel@tonic-gate 				    col->col_paged_eff /
2147c478bd9Sstevel@tonic-gate 				    (report.lcol_stat.lcols_scan_count -
2157c478bd9Sstevel@tonic-gate 				    col->col_count);
2167c478bd9Sstevel@tonic-gate 		} else {
2177c478bd9Sstevel@tonic-gate 			col->col_paged_eff_avg = 0;
2187c478bd9Sstevel@tonic-gate 		}
2197c478bd9Sstevel@tonic-gate 		if (report.lcol_stat.lcols_pg_att > col->col_paged_att_old) {
2207c478bd9Sstevel@tonic-gate 			col->col_paged_att =
2217c478bd9Sstevel@tonic-gate 			    report.lcol_stat.lcols_pg_att -
2227c478bd9Sstevel@tonic-gate 			    col->col_paged_att_old;
2237c478bd9Sstevel@tonic-gate 			if (report.lcol_stat.lcols_scan_count > col->col_count)
2247c478bd9Sstevel@tonic-gate 				col->col_paged_att_avg =
2257c478bd9Sstevel@tonic-gate 				    col->col_paged_att /
2267c478bd9Sstevel@tonic-gate 				    (report.lcol_stat.lcols_scan_count -
2277c478bd9Sstevel@tonic-gate 				    col->col_count);
2287c478bd9Sstevel@tonic-gate 		} else {
2297c478bd9Sstevel@tonic-gate 			col->col_paged_att_avg = 0;
2307c478bd9Sstevel@tonic-gate 		}
2317c478bd9Sstevel@tonic-gate 		col->col_paged_eff_old = report.lcol_stat.lcols_pg_eff;
2327c478bd9Sstevel@tonic-gate 		col->col_paged_att_old = report.lcol_stat.lcols_pg_att;
2337c478bd9Sstevel@tonic-gate 		col->col_nproc =
2347c478bd9Sstevel@tonic-gate 		    report.lcol_stat.lcols_proc_in -
2357c478bd9Sstevel@tonic-gate 		    report.lcol_stat.lcols_proc_out;
2367c478bd9Sstevel@tonic-gate 		col->col_count = report.lcol_stat.lcols_scan_count;
2377c478bd9Sstevel@tonic-gate 		col->col_src_stat = report.lcol_stat;
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	/*
2417c478bd9Sstevel@tonic-gate 	 * Remove stale data
2427c478bd9Sstevel@tonic-gate 	 */
2437c478bd9Sstevel@tonic-gate 	col = col_head;
2447c478bd9Sstevel@tonic-gate 	while (col != NULL) {
2457c478bd9Sstevel@tonic-gate 		col_next = col->col_next;
2467c478bd9Sstevel@tonic-gate 		if (col->col_fresh == 0)
2477c478bd9Sstevel@tonic-gate 			col_remove(col);
2487c478bd9Sstevel@tonic-gate 		col = col_next;
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 	(void) close(fd);
2517c478bd9Sstevel@tonic-gate 	return (E_SUCCESS);
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate /*
2557c478bd9Sstevel@tonic-gate  * Print each collection's interval statistics.
2567c478bd9Sstevel@tonic-gate  */
2577c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2587c478bd9Sstevel@tonic-gate static void
2597c478bd9Sstevel@tonic-gate print_unformatted_stats(void)
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate 	col_t *col;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate #define	DELTA(field) \
2647c478bd9Sstevel@tonic-gate 	(col->col_src_stat.field - col->col_old_stat.field)
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	col = col_head;
2677c478bd9Sstevel@tonic-gate 	while (col != NULL) {
2687c478bd9Sstevel@tonic-gate 		if (bcmp(&col->col_src_stat, &col->col_old_stat,
2697c478bd9Sstevel@tonic-gate 		    sizeof (col->col_src_stat)) == 0) {
2707c478bd9Sstevel@tonic-gate 			col = col->col_next;
2717c478bd9Sstevel@tonic-gate 			continue;
2727c478bd9Sstevel@tonic-gate 		}
2737c478bd9Sstevel@tonic-gate 		(void) printf("%s %s status: succeeded/attempted (k): "
2747c478bd9Sstevel@tonic-gate 		    "%llu/%llu, ineffective/scans/unenforced/samplings:  "
2757c478bd9Sstevel@tonic-gate 		    "%llu/%llu/%llu/%llu, RSS min/max (k): %llu/%llu, cap %llu "
2767c478bd9Sstevel@tonic-gate 		    "kB, processes/thpt: %llu/%llu, %llu scans over %lld ms\n",
2777c478bd9Sstevel@tonic-gate 		    mode, col->col_name, DELTA(lcols_pg_eff),
2787c478bd9Sstevel@tonic-gate 		    DELTA(lcols_pg_att), DELTA(lcols_scan_ineffective),
2797c478bd9Sstevel@tonic-gate 		    DELTA(lcols_scan), DELTA(lcols_unenforced_cap),
2807c478bd9Sstevel@tonic-gate 		    DELTA(lcols_rss_sample), col->col_src_stat.lcols_min_rss,
2817c478bd9Sstevel@tonic-gate 		    col->col_src_stat.lcols_max_rss, col->col_rsslimit,
2827c478bd9Sstevel@tonic-gate 		    (col->col_src_stat.lcols_proc_in -
2837c478bd9Sstevel@tonic-gate 		    col->col_old_stat.lcols_proc_out), DELTA(lcols_proc_out),
284*19449258SJosef 'Jeff' Sipek 		    DELTA(lcols_scan_count),
285*19449258SJosef 'Jeff' Sipek 		    NSEC2MSEC(DELTA(lcols_scan_time_complete)));
2867c478bd9Sstevel@tonic-gate 		col->col_old_stat = col->col_src_stat;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 		col = col->col_next;
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	if (global)
2927c478bd9Sstevel@tonic-gate 		(void) printf(gettext("physical memory utilization: %3u%%   "
2937c478bd9Sstevel@tonic-gate 		    "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur,
2947c478bd9Sstevel@tonic-gate 		    hdr.rs_pressure_cap);
2957c478bd9Sstevel@tonic-gate #undef DELTA
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate static void
2990209230bSgjelinek print_stats(rcid_type_t stat_type)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate 	col_t *col;
3027c478bd9Sstevel@tonic-gate 	char size[6];
3037c478bd9Sstevel@tonic-gate 	char limit[6];
3047c478bd9Sstevel@tonic-gate 	char rss[6];
3050209230bSgjelinek 	char nproc[6];
3067c478bd9Sstevel@tonic-gate 	char paged_att[6];
3077c478bd9Sstevel@tonic-gate 	char paged_eff[6];
3087c478bd9Sstevel@tonic-gate 	char paged_att_avg[6];
3097c478bd9Sstevel@tonic-gate 	char paged_eff_avg[6];
3107c478bd9Sstevel@tonic-gate 	static int count = 0;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	/*
3137c478bd9Sstevel@tonic-gate 	 * Print a header once every 20 times if we're only displaying reports
3147c478bd9Sstevel@tonic-gate 	 * for one collection (10 times if -g is used).  Print a header every
3157c478bd9Sstevel@tonic-gate 	 * interval otherwise.
3167c478bd9Sstevel@tonic-gate 	 */
3177c478bd9Sstevel@tonic-gate 	if (count == 0 || ncol != 1)
3187c478bd9Sstevel@tonic-gate 		(void) printf("%6s %-15s %5s %5s %5s %5s %5s %5s %5s %5s\n",
3190209230bSgjelinek 		    "id", (stat_type == RCIDT_PROJECT ?  "project" : "zone"),
3200209230bSgjelinek 		    "nproc", "vm", "rss", "cap",
3217c478bd9Sstevel@tonic-gate 		    "at", "avgat", "pg", "avgpg");
3227c478bd9Sstevel@tonic-gate 	if (++count >= 20 || (count >= 10 && global != 0) || ncol != 1)
3237c478bd9Sstevel@tonic-gate 		count = 0;
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	for (col = col_head; col != NULL; col = col->col_next) {
3260209230bSgjelinek 		if (col->col_id.rcid_type != stat_type)
3270209230bSgjelinek 			continue;
3280209230bSgjelinek 
3290209230bSgjelinek 		if (col->col_paged_att == 0)
330206f543eStn143363 			(void) strlcpy(nproc, "-", sizeof (nproc));
3310209230bSgjelinek 		else
3320209230bSgjelinek 			(void) snprintf(nproc, sizeof (nproc), "%lld",
3330209230bSgjelinek 			    col->col_nproc);
3347c478bd9Sstevel@tonic-gate 		format_size(size, col->col_vmsize, 6);
3357c478bd9Sstevel@tonic-gate 		format_size(rss, col->col_rsssize, 6);
3367c478bd9Sstevel@tonic-gate 		format_size(limit, col->col_rsslimit, 6);
3377c478bd9Sstevel@tonic-gate 		format_size(paged_att, col->col_paged_att, 6);
3387c478bd9Sstevel@tonic-gate 		format_size(paged_eff, col->col_paged_eff, 6);
3397c478bd9Sstevel@tonic-gate 		format_size(paged_att_avg, col->col_paged_att_avg, 6);
3407c478bd9Sstevel@tonic-gate 		format_size(paged_eff_avg, col->col_paged_eff_avg, 6);
3410209230bSgjelinek 		(void) printf("%6lld %-15s %5s %5s %5s %5s %5s %5s %5s %5s\n",
3420209230bSgjelinek 		    col->col_id.rcid_val, col->col_name,
3430209230bSgjelinek 		    nproc,
3447c478bd9Sstevel@tonic-gate 		    size, rss, limit,
3457c478bd9Sstevel@tonic-gate 		    paged_att, paged_att_avg,
3467c478bd9Sstevel@tonic-gate 		    paged_eff, paged_eff_avg);
3477c478bd9Sstevel@tonic-gate 	}
3487c478bd9Sstevel@tonic-gate 	if (global)
3497c478bd9Sstevel@tonic-gate 		(void) printf(gettext("physical memory utilization: %3u%%   "
3507c478bd9Sstevel@tonic-gate 		    "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur,
3517c478bd9Sstevel@tonic-gate 		    hdr.rs_pressure_cap);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate int
3557c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
3567c478bd9Sstevel@tonic-gate {
3577c478bd9Sstevel@tonic-gate 	int interval = 5;
3587c478bd9Sstevel@tonic-gate 	int count;
3597c478bd9Sstevel@tonic-gate 	int always = 1;
3607c478bd9Sstevel@tonic-gate 	int opt;
3610209230bSgjelinek 	int projects = 0;
3620209230bSgjelinek 	int zones = 0;
3630209230bSgjelinek 	/* project reporting is the default if no option is specified */
3640209230bSgjelinek 	rcid_type_t stat_type = RCIDT_PROJECT;
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
3677c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
36823a1cceaSRoger A. Faulkner 	(void) setpname("rcapstat");
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	global = unformatted = 0;
37126fd7700SKrishnendu Sadhukhan - Sun Microsystems 	while ((opt = getopt(argc, argv, "gpuzT:")) != (int)EOF) {
3727c478bd9Sstevel@tonic-gate 		switch (opt) {
3737c478bd9Sstevel@tonic-gate 		case 'g':
3747c478bd9Sstevel@tonic-gate 			global = 1;
3757c478bd9Sstevel@tonic-gate 			break;
3760209230bSgjelinek 		case 'p':
3770209230bSgjelinek 			projects = 1;
3780209230bSgjelinek 			stat_type = RCIDT_PROJECT;
3790209230bSgjelinek 			break;
3807c478bd9Sstevel@tonic-gate 		case 'u':
3817c478bd9Sstevel@tonic-gate 			unformatted = 1;
3827c478bd9Sstevel@tonic-gate 			break;
3830209230bSgjelinek 		case 'z':
3840209230bSgjelinek 			stat_type = RCIDT_ZONE;
3850209230bSgjelinek 			zones = 1;
3860209230bSgjelinek 			break;
38726fd7700SKrishnendu Sadhukhan - Sun Microsystems 		case 'T':
38826fd7700SKrishnendu Sadhukhan - Sun Microsystems 			if (optarg) {
38926fd7700SKrishnendu Sadhukhan - Sun Microsystems 				if (*optarg == 'u')
39026fd7700SKrishnendu Sadhukhan - Sun Microsystems 					timestamp_fmt = UDATE;
39126fd7700SKrishnendu Sadhukhan - Sun Microsystems 				else if (*optarg == 'd')
39226fd7700SKrishnendu Sadhukhan - Sun Microsystems 					timestamp_fmt = DDATE;
39326fd7700SKrishnendu Sadhukhan - Sun Microsystems 				else
39426fd7700SKrishnendu Sadhukhan - Sun Microsystems 					usage();
39526fd7700SKrishnendu Sadhukhan - Sun Microsystems 			} else {
39626fd7700SKrishnendu Sadhukhan - Sun Microsystems 				usage();
39726fd7700SKrishnendu Sadhukhan - Sun Microsystems 			}
39826fd7700SKrishnendu Sadhukhan - Sun Microsystems 			break;
3997c478bd9Sstevel@tonic-gate 		default:
4007c478bd9Sstevel@tonic-gate 			usage();
4017c478bd9Sstevel@tonic-gate 		}
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	if (argc > optind)
4057c478bd9Sstevel@tonic-gate 		if ((interval = xatoi(argv[optind++])) <= 0)
4067c478bd9Sstevel@tonic-gate 			die(gettext("invalid interval specified\n"));
4077c478bd9Sstevel@tonic-gate 	if (argc > optind) {
4087c478bd9Sstevel@tonic-gate 		if ((count = xatoi(argv[optind++])) <= 0)
4097c478bd9Sstevel@tonic-gate 			die(gettext("invalid count specified\n"));
4107c478bd9Sstevel@tonic-gate 		always = 0;
4117c478bd9Sstevel@tonic-gate 	}
4120209230bSgjelinek 	if (argc > optind || (projects > 0 && zones > 0))
4137c478bd9Sstevel@tonic-gate 		usage();
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 	while (always || count-- > 0) {
4160209230bSgjelinek 		if (read_stats(stat_type) != E_SUCCESS)
4177c478bd9Sstevel@tonic-gate 			return (E_ERROR);
41826fd7700SKrishnendu Sadhukhan - Sun Microsystems 		if (timestamp_fmt != NODATE)
41926fd7700SKrishnendu Sadhukhan - Sun Microsystems 			print_timestamp(timestamp_fmt);
4207c478bd9Sstevel@tonic-gate 		if (!unformatted) {
4210209230bSgjelinek 			print_stats(stat_type);
4220209230bSgjelinek 			(void) fflush(stdout);
4237c478bd9Sstevel@tonic-gate 			if (count || always)
4247c478bd9Sstevel@tonic-gate 				(void) sleep(interval);
4257c478bd9Sstevel@tonic-gate 		} else {
4267c478bd9Sstevel@tonic-gate 			struct stat st;
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 			print_unformatted_stats();
4290209230bSgjelinek 			(void) fflush(stdout);
4307c478bd9Sstevel@tonic-gate 			while (stat(STAT_FILE_DEFAULT, &st) == 0 &&
4317c478bd9Sstevel@tonic-gate 			    st.st_mtime == stat_mod)
432206f543eStn143363 				(void) usleep((useconds_t)(0.2 * MICROSEC));
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 	return (E_SUCCESS);
4377c478bd9Sstevel@tonic-gate }
438