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 */ 217c478bd9Sstevel@tonic-gate /* 22*206f543eStn143363 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <sys/stat.h> 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <fcntl.h> 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <string.h> 367c478bd9Sstevel@tonic-gate #include <strings.h> 377c478bd9Sstevel@tonic-gate #include <libintl.h> 387c478bd9Sstevel@tonic-gate #include <locale.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include "rcapd.h" 417c478bd9Sstevel@tonic-gate #include "utils.h" 427c478bd9Sstevel@tonic-gate #include "rcapd_stat.h" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate static char mode[RC_MODE_LEN]; 457c478bd9Sstevel@tonic-gate static rcapd_stat_hdr_t hdr; 467c478bd9Sstevel@tonic-gate static int global; 477c478bd9Sstevel@tonic-gate static int unformatted; 487c478bd9Sstevel@tonic-gate static time_t stat_mod = 0; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate typedef struct col { 517c478bd9Sstevel@tonic-gate rcid_t col_id; 527c478bd9Sstevel@tonic-gate char col_name[LC_NAME_LEN]; 537c478bd9Sstevel@tonic-gate uint64_t col_nproc; 547c478bd9Sstevel@tonic-gate uint64_t col_vmsize; 557c478bd9Sstevel@tonic-gate uint64_t col_rsssize; 567c478bd9Sstevel@tonic-gate uint64_t col_rsslimit; 577c478bd9Sstevel@tonic-gate uint64_t col_paged_eff; 587c478bd9Sstevel@tonic-gate uint64_t col_paged_eff_old; 597c478bd9Sstevel@tonic-gate uint64_t col_paged_eff_avg; 607c478bd9Sstevel@tonic-gate uint64_t col_paged_att; 617c478bd9Sstevel@tonic-gate uint64_t col_paged_att_old; 627c478bd9Sstevel@tonic-gate uint64_t col_paged_att_avg; 637c478bd9Sstevel@tonic-gate uint64_t col_count; 647c478bd9Sstevel@tonic-gate int col_fresh; 657c478bd9Sstevel@tonic-gate struct col *col_next; 667c478bd9Sstevel@tonic-gate struct col *col_prev; 677c478bd9Sstevel@tonic-gate lcollection_stat_t col_src_stat; 687c478bd9Sstevel@tonic-gate lcollection_stat_t col_old_stat; 697c478bd9Sstevel@tonic-gate } col_t; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate static col_t *col_head; 727c478bd9Sstevel@tonic-gate static int ncol; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate static col_t * 757c478bd9Sstevel@tonic-gate col_find(rcid_t id) 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate col_t *col; 787c478bd9Sstevel@tonic-gate for (col = col_head; col != NULL; col = col->col_next) 790209230bSgjelinek if (col->col_id.rcid_type == id.rcid_type && 800209230bSgjelinek col->col_id.rcid_val == id.rcid_val) 817c478bd9Sstevel@tonic-gate return (col); 827c478bd9Sstevel@tonic-gate return (NULL); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate static col_t * 867c478bd9Sstevel@tonic-gate col_insert(rcid_t id) 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate col_t *new_col; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate new_col = malloc(sizeof (col_t)); 917c478bd9Sstevel@tonic-gate if (new_col == NULL) { 927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("rcapstat: malloc() failed\n")); 937c478bd9Sstevel@tonic-gate exit(E_ERROR); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate (void) memset(new_col, 0, sizeof (col_t)); 967c478bd9Sstevel@tonic-gate new_col->col_next = col_head; 977c478bd9Sstevel@tonic-gate new_col->col_id = id; 987c478bd9Sstevel@tonic-gate if (col_head != NULL) 997c478bd9Sstevel@tonic-gate col_head->col_prev = new_col; 1007c478bd9Sstevel@tonic-gate col_head = new_col; 1017c478bd9Sstevel@tonic-gate ncol++; 1027c478bd9Sstevel@tonic-gate return (new_col); 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate static void 1067c478bd9Sstevel@tonic-gate col_remove(col_t *col) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate if (col->col_prev != NULL) 1097c478bd9Sstevel@tonic-gate col->col_prev->col_next = col->col_next; 1107c478bd9Sstevel@tonic-gate if (col->col_next != NULL) 1117c478bd9Sstevel@tonic-gate col->col_next->col_prev = col->col_prev; 1127c478bd9Sstevel@tonic-gate if (col_head == col) 1137c478bd9Sstevel@tonic-gate col_head = col->col_next; 1147c478bd9Sstevel@tonic-gate ncol--; 1157c478bd9Sstevel@tonic-gate free(col); 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate static void 1197c478bd9Sstevel@tonic-gate usage() 1207c478bd9Sstevel@tonic-gate { 1217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1220209230bSgjelinek gettext("usage: rcapstat [-g] [-p | -z] [interval [count]]\n")); 1237c478bd9Sstevel@tonic-gate exit(E_USAGE); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate static void 1277c478bd9Sstevel@tonic-gate format_size(char *str, uint64_t size, int length) 1287c478bd9Sstevel@tonic-gate { 1297c478bd9Sstevel@tonic-gate char tag = 'K'; 1307c478bd9Sstevel@tonic-gate if (size >= 10000) { 1317c478bd9Sstevel@tonic-gate size = (size + 512) / 1024; 1327c478bd9Sstevel@tonic-gate tag = 'M'; 1337c478bd9Sstevel@tonic-gate if (size >= 10000) { 1347c478bd9Sstevel@tonic-gate size = (size + 512) / 1024; 1357c478bd9Sstevel@tonic-gate tag = 'G'; 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate (void) snprintf(str, length, "%4lld%c", size, tag); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate static int 1420209230bSgjelinek read_stats(rcid_type_t stat_type) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate int fd; 1457c478bd9Sstevel@tonic-gate int proc_fd; 1467c478bd9Sstevel@tonic-gate char procfile[20]; 1470209230bSgjelinek uint64_t pid; 1487c478bd9Sstevel@tonic-gate col_t *col, *col_next; 1497c478bd9Sstevel@tonic-gate lcollection_report_t report; 1507c478bd9Sstevel@tonic-gate struct stat st; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate if ((fd = open(STAT_FILE_DEFAULT, O_RDONLY)) < 0) { 1537c478bd9Sstevel@tonic-gate warn(gettext("rcapd is not active\n")); 1547c478bd9Sstevel@tonic-gate return (E_ERROR); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate if (fstat(fd, &st) == 0) 1587c478bd9Sstevel@tonic-gate stat_mod = st.st_mtime; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate if (read(fd, &hdr, sizeof (hdr)) != sizeof (hdr)) { 1617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1627c478bd9Sstevel@tonic-gate gettext("rcapstat: can't read stat file header: %s\n"), 1637c478bd9Sstevel@tonic-gate strerror(errno)); 1647c478bd9Sstevel@tonic-gate (void) close(fd); 1657c478bd9Sstevel@tonic-gate return (E_ERROR); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate /* 1697c478bd9Sstevel@tonic-gate * Check if rcapd is running 1707c478bd9Sstevel@tonic-gate */ 1717c478bd9Sstevel@tonic-gate pid = hdr.rs_pid; 1720209230bSgjelinek (void) snprintf(procfile, 20, "/proc/%lld/psinfo", pid); 1737c478bd9Sstevel@tonic-gate if ((proc_fd = open(procfile, O_RDONLY)) < 0) { 1747c478bd9Sstevel@tonic-gate warn(gettext("rcapd is not active\n")); 1757c478bd9Sstevel@tonic-gate (void) close(fd); 1767c478bd9Sstevel@tonic-gate return (E_ERROR); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate (void) close(proc_fd); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate (void) strncpy(mode, hdr.rs_mode, RC_MODE_LEN); 1817c478bd9Sstevel@tonic-gate for (col = col_head; col != NULL; col = col->col_next) { 1827c478bd9Sstevel@tonic-gate col->col_fresh = 0; 1837c478bd9Sstevel@tonic-gate col->col_paged_eff = 0; 1847c478bd9Sstevel@tonic-gate col->col_paged_att = 0; 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate while (read(fd, &report, sizeof (report)) == sizeof (report)) { 1880209230bSgjelinek if (report.lcol_id.rcid_type != stat_type) 1890209230bSgjelinek continue; 1900209230bSgjelinek 1917c478bd9Sstevel@tonic-gate col = col_find(report.lcol_id); 1927c478bd9Sstevel@tonic-gate if (col == NULL) { 1937c478bd9Sstevel@tonic-gate col = col_insert(report.lcol_id); 1947c478bd9Sstevel@tonic-gate col->col_paged_eff_old = col->col_paged_eff = 1957c478bd9Sstevel@tonic-gate report.lcol_stat.lcols_pg_eff; 1967c478bd9Sstevel@tonic-gate col->col_paged_att_old = col->col_paged_att = 1977c478bd9Sstevel@tonic-gate report.lcol_stat.lcols_pg_att; 1987c478bd9Sstevel@tonic-gate col->col_count = 0; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate (void) strncpy(col->col_name, report.lcol_name, LC_NAME_LEN); 2017c478bd9Sstevel@tonic-gate col->col_vmsize = report.lcol_image_size; 2027c478bd9Sstevel@tonic-gate col->col_rsssize = report.lcol_rss; 2037c478bd9Sstevel@tonic-gate col->col_rsslimit = report.lcol_rss_cap; 2047c478bd9Sstevel@tonic-gate col->col_fresh = 1; 2057c478bd9Sstevel@tonic-gate if (report.lcol_stat.lcols_pg_eff > col->col_paged_eff_old) { 2067c478bd9Sstevel@tonic-gate col->col_paged_eff = 2077c478bd9Sstevel@tonic-gate report.lcol_stat.lcols_pg_eff - 2087c478bd9Sstevel@tonic-gate col->col_paged_eff_old; 2097c478bd9Sstevel@tonic-gate if (report.lcol_stat.lcols_scan_count > col->col_count) 2107c478bd9Sstevel@tonic-gate col->col_paged_eff_avg = 2117c478bd9Sstevel@tonic-gate col->col_paged_eff / 2127c478bd9Sstevel@tonic-gate (report.lcol_stat.lcols_scan_count - 2137c478bd9Sstevel@tonic-gate col->col_count); 2147c478bd9Sstevel@tonic-gate } else { 2157c478bd9Sstevel@tonic-gate col->col_paged_eff_avg = 0; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate if (report.lcol_stat.lcols_pg_att > col->col_paged_att_old) { 2187c478bd9Sstevel@tonic-gate col->col_paged_att = 2197c478bd9Sstevel@tonic-gate report.lcol_stat.lcols_pg_att - 2207c478bd9Sstevel@tonic-gate col->col_paged_att_old; 2217c478bd9Sstevel@tonic-gate if (report.lcol_stat.lcols_scan_count > col->col_count) 2227c478bd9Sstevel@tonic-gate col->col_paged_att_avg = 2237c478bd9Sstevel@tonic-gate col->col_paged_att / 2247c478bd9Sstevel@tonic-gate (report.lcol_stat.lcols_scan_count - 2257c478bd9Sstevel@tonic-gate col->col_count); 2267c478bd9Sstevel@tonic-gate } else { 2277c478bd9Sstevel@tonic-gate col->col_paged_att_avg = 0; 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate col->col_paged_eff_old = report.lcol_stat.lcols_pg_eff; 2307c478bd9Sstevel@tonic-gate col->col_paged_att_old = report.lcol_stat.lcols_pg_att; 2317c478bd9Sstevel@tonic-gate col->col_nproc = 2327c478bd9Sstevel@tonic-gate report.lcol_stat.lcols_proc_in - 2337c478bd9Sstevel@tonic-gate report.lcol_stat.lcols_proc_out; 2347c478bd9Sstevel@tonic-gate col->col_count = report.lcol_stat.lcols_scan_count; 2357c478bd9Sstevel@tonic-gate col->col_src_stat = report.lcol_stat; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate /* 2397c478bd9Sstevel@tonic-gate * Remove stale data 2407c478bd9Sstevel@tonic-gate */ 2417c478bd9Sstevel@tonic-gate col = col_head; 2427c478bd9Sstevel@tonic-gate while (col != NULL) { 2437c478bd9Sstevel@tonic-gate col_next = col->col_next; 2447c478bd9Sstevel@tonic-gate if (col->col_fresh == 0) 2457c478bd9Sstevel@tonic-gate col_remove(col); 2467c478bd9Sstevel@tonic-gate col = col_next; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate (void) close(fd); 2497c478bd9Sstevel@tonic-gate return (E_SUCCESS); 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate /* 2537c478bd9Sstevel@tonic-gate * Print each collection's interval statistics. 2547c478bd9Sstevel@tonic-gate */ 2557c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2567c478bd9Sstevel@tonic-gate static void 2577c478bd9Sstevel@tonic-gate print_unformatted_stats(void) 2587c478bd9Sstevel@tonic-gate { 2597c478bd9Sstevel@tonic-gate col_t *col; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate #define DELTA(field) \ 2627c478bd9Sstevel@tonic-gate (col->col_src_stat.field - col->col_old_stat.field) 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate col = col_head; 2657c478bd9Sstevel@tonic-gate while (col != NULL) { 2667c478bd9Sstevel@tonic-gate if (bcmp(&col->col_src_stat, &col->col_old_stat, 2677c478bd9Sstevel@tonic-gate sizeof (col->col_src_stat)) == 0) { 2687c478bd9Sstevel@tonic-gate col = col->col_next; 2697c478bd9Sstevel@tonic-gate continue; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate (void) printf("%s %s status: succeeded/attempted (k): " 2727c478bd9Sstevel@tonic-gate "%llu/%llu, ineffective/scans/unenforced/samplings: " 2737c478bd9Sstevel@tonic-gate "%llu/%llu/%llu/%llu, RSS min/max (k): %llu/%llu, cap %llu " 2747c478bd9Sstevel@tonic-gate "kB, processes/thpt: %llu/%llu, %llu scans over %lld ms\n", 2757c478bd9Sstevel@tonic-gate mode, col->col_name, DELTA(lcols_pg_eff), 2767c478bd9Sstevel@tonic-gate DELTA(lcols_pg_att), DELTA(lcols_scan_ineffective), 2777c478bd9Sstevel@tonic-gate DELTA(lcols_scan), DELTA(lcols_unenforced_cap), 2787c478bd9Sstevel@tonic-gate DELTA(lcols_rss_sample), col->col_src_stat.lcols_min_rss, 2797c478bd9Sstevel@tonic-gate col->col_src_stat.lcols_max_rss, col->col_rsslimit, 2807c478bd9Sstevel@tonic-gate (col->col_src_stat.lcols_proc_in - 2817c478bd9Sstevel@tonic-gate col->col_old_stat.lcols_proc_out), DELTA(lcols_proc_out), 2827c478bd9Sstevel@tonic-gate DELTA(lcols_scan_count), DELTA(lcols_scan_time_complete) / 2837c478bd9Sstevel@tonic-gate (NANOSEC / MILLISEC)); 2847c478bd9Sstevel@tonic-gate col->col_old_stat = col->col_src_stat; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate col = col->col_next; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate if (global) 2907c478bd9Sstevel@tonic-gate (void) printf(gettext("physical memory utilization: %3u%% " 2917c478bd9Sstevel@tonic-gate "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur, 2927c478bd9Sstevel@tonic-gate hdr.rs_pressure_cap); 2937c478bd9Sstevel@tonic-gate #undef DELTA 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate static void 2970209230bSgjelinek print_stats(rcid_type_t stat_type) 2987c478bd9Sstevel@tonic-gate { 2997c478bd9Sstevel@tonic-gate col_t *col; 3007c478bd9Sstevel@tonic-gate char size[6]; 3017c478bd9Sstevel@tonic-gate char limit[6]; 3027c478bd9Sstevel@tonic-gate char rss[6]; 3030209230bSgjelinek char nproc[6]; 3047c478bd9Sstevel@tonic-gate char paged_att[6]; 3057c478bd9Sstevel@tonic-gate char paged_eff[6]; 3067c478bd9Sstevel@tonic-gate char paged_att_avg[6]; 3077c478bd9Sstevel@tonic-gate char paged_eff_avg[6]; 3087c478bd9Sstevel@tonic-gate static int count = 0; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Print a header once every 20 times if we're only displaying reports 3127c478bd9Sstevel@tonic-gate * for one collection (10 times if -g is used). Print a header every 3137c478bd9Sstevel@tonic-gate * interval otherwise. 3147c478bd9Sstevel@tonic-gate */ 3157c478bd9Sstevel@tonic-gate if (count == 0 || ncol != 1) 3167c478bd9Sstevel@tonic-gate (void) printf("%6s %-15s %5s %5s %5s %5s %5s %5s %5s %5s\n", 3170209230bSgjelinek "id", (stat_type == RCIDT_PROJECT ? "project" : "zone"), 3180209230bSgjelinek "nproc", "vm", "rss", "cap", 3197c478bd9Sstevel@tonic-gate "at", "avgat", "pg", "avgpg"); 3207c478bd9Sstevel@tonic-gate if (++count >= 20 || (count >= 10 && global != 0) || ncol != 1) 3217c478bd9Sstevel@tonic-gate count = 0; 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate for (col = col_head; col != NULL; col = col->col_next) { 3240209230bSgjelinek if (col->col_id.rcid_type != stat_type) 3250209230bSgjelinek continue; 3260209230bSgjelinek 3270209230bSgjelinek if (col->col_paged_att == 0) 328*206f543eStn143363 (void) strlcpy(nproc, "-", sizeof (nproc)); 3290209230bSgjelinek else 3300209230bSgjelinek (void) snprintf(nproc, sizeof (nproc), "%lld", 3310209230bSgjelinek col->col_nproc); 3327c478bd9Sstevel@tonic-gate format_size(size, col->col_vmsize, 6); 3337c478bd9Sstevel@tonic-gate format_size(rss, col->col_rsssize, 6); 3347c478bd9Sstevel@tonic-gate format_size(limit, col->col_rsslimit, 6); 3357c478bd9Sstevel@tonic-gate format_size(paged_att, col->col_paged_att, 6); 3367c478bd9Sstevel@tonic-gate format_size(paged_eff, col->col_paged_eff, 6); 3377c478bd9Sstevel@tonic-gate format_size(paged_att_avg, col->col_paged_att_avg, 6); 3387c478bd9Sstevel@tonic-gate format_size(paged_eff_avg, col->col_paged_eff_avg, 6); 3390209230bSgjelinek (void) printf("%6lld %-15s %5s %5s %5s %5s %5s %5s %5s %5s\n", 3400209230bSgjelinek col->col_id.rcid_val, col->col_name, 3410209230bSgjelinek nproc, 3427c478bd9Sstevel@tonic-gate size, rss, limit, 3437c478bd9Sstevel@tonic-gate paged_att, paged_att_avg, 3447c478bd9Sstevel@tonic-gate paged_eff, paged_eff_avg); 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate if (global) 3477c478bd9Sstevel@tonic-gate (void) printf(gettext("physical memory utilization: %3u%% " 3487c478bd9Sstevel@tonic-gate "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur, 3497c478bd9Sstevel@tonic-gate hdr.rs_pressure_cap); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate int 3537c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 3547c478bd9Sstevel@tonic-gate { 3557c478bd9Sstevel@tonic-gate int interval = 5; 3567c478bd9Sstevel@tonic-gate int count; 3577c478bd9Sstevel@tonic-gate int always = 1; 3587c478bd9Sstevel@tonic-gate int opt; 3590209230bSgjelinek int projects = 0; 3600209230bSgjelinek int zones = 0; 3610209230bSgjelinek /* project reporting is the default if no option is specified */ 3620209230bSgjelinek rcid_type_t stat_type = RCIDT_PROJECT; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 3657c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 3667c478bd9Sstevel@tonic-gate (void) setprogname("rcapstat"); 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate global = unformatted = 0; 3690209230bSgjelinek while ((opt = getopt(argc, argv, "gpuz")) != (int)EOF) { 3707c478bd9Sstevel@tonic-gate switch (opt) { 3717c478bd9Sstevel@tonic-gate case 'g': 3727c478bd9Sstevel@tonic-gate global = 1; 3737c478bd9Sstevel@tonic-gate break; 3740209230bSgjelinek case 'p': 3750209230bSgjelinek projects = 1; 3760209230bSgjelinek stat_type = RCIDT_PROJECT; 3770209230bSgjelinek break; 3787c478bd9Sstevel@tonic-gate case 'u': 3797c478bd9Sstevel@tonic-gate unformatted = 1; 3807c478bd9Sstevel@tonic-gate break; 3810209230bSgjelinek case 'z': 3820209230bSgjelinek stat_type = RCIDT_ZONE; 3830209230bSgjelinek zones = 1; 3840209230bSgjelinek break; 3857c478bd9Sstevel@tonic-gate default: 3867c478bd9Sstevel@tonic-gate usage(); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate if (argc > optind) 3917c478bd9Sstevel@tonic-gate if ((interval = xatoi(argv[optind++])) <= 0) 3927c478bd9Sstevel@tonic-gate die(gettext("invalid interval specified\n")); 3937c478bd9Sstevel@tonic-gate if (argc > optind) { 3947c478bd9Sstevel@tonic-gate if ((count = xatoi(argv[optind++])) <= 0) 3957c478bd9Sstevel@tonic-gate die(gettext("invalid count specified\n")); 3967c478bd9Sstevel@tonic-gate always = 0; 3977c478bd9Sstevel@tonic-gate } 3980209230bSgjelinek if (argc > optind || (projects > 0 && zones > 0)) 3997c478bd9Sstevel@tonic-gate usage(); 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate while (always || count-- > 0) { 4020209230bSgjelinek if (read_stats(stat_type) != E_SUCCESS) 4037c478bd9Sstevel@tonic-gate return (E_ERROR); 4047c478bd9Sstevel@tonic-gate if (!unformatted) { 4050209230bSgjelinek print_stats(stat_type); 4060209230bSgjelinek (void) fflush(stdout); 4077c478bd9Sstevel@tonic-gate if (count || always) 4087c478bd9Sstevel@tonic-gate (void) sleep(interval); 4097c478bd9Sstevel@tonic-gate } else { 4107c478bd9Sstevel@tonic-gate struct stat st; 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate print_unformatted_stats(); 4130209230bSgjelinek (void) fflush(stdout); 4147c478bd9Sstevel@tonic-gate while (stat(STAT_FILE_DEFAULT, &st) == 0 && 4157c478bd9Sstevel@tonic-gate st.st_mtime == stat_mod) 416*206f543eStn143363 (void) usleep((useconds_t)(0.2 * MICROSEC)); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate return (E_SUCCESS); 4217c478bd9Sstevel@tonic-gate } 422