10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 53247Sgjelinek * Common Development and Distribution License (the "License"). 63247Sgjelinek * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*4131Stn143363 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/types.h> 290Sstevel@tonic-gate #include <sys/stat.h> 300Sstevel@tonic-gate #include <stdlib.h> 310Sstevel@tonic-gate #include <fcntl.h> 320Sstevel@tonic-gate #include <errno.h> 330Sstevel@tonic-gate #include <stdio.h> 340Sstevel@tonic-gate #include <unistd.h> 350Sstevel@tonic-gate #include <string.h> 360Sstevel@tonic-gate #include <strings.h> 370Sstevel@tonic-gate #include <libintl.h> 380Sstevel@tonic-gate #include <locale.h> 390Sstevel@tonic-gate 400Sstevel@tonic-gate #include "rcapd.h" 410Sstevel@tonic-gate #include "utils.h" 420Sstevel@tonic-gate #include "rcapd_stat.h" 430Sstevel@tonic-gate 440Sstevel@tonic-gate static char mode[RC_MODE_LEN]; 450Sstevel@tonic-gate static rcapd_stat_hdr_t hdr; 460Sstevel@tonic-gate static int global; 470Sstevel@tonic-gate static int unformatted; 480Sstevel@tonic-gate static time_t stat_mod = 0; 490Sstevel@tonic-gate 500Sstevel@tonic-gate typedef struct col { 510Sstevel@tonic-gate rcid_t col_id; 520Sstevel@tonic-gate char col_name[LC_NAME_LEN]; 530Sstevel@tonic-gate uint64_t col_nproc; 540Sstevel@tonic-gate uint64_t col_vmsize; 550Sstevel@tonic-gate uint64_t col_rsssize; 560Sstevel@tonic-gate uint64_t col_rsslimit; 570Sstevel@tonic-gate uint64_t col_paged_eff; 580Sstevel@tonic-gate uint64_t col_paged_eff_old; 590Sstevel@tonic-gate uint64_t col_paged_eff_avg; 600Sstevel@tonic-gate uint64_t col_paged_att; 610Sstevel@tonic-gate uint64_t col_paged_att_old; 620Sstevel@tonic-gate uint64_t col_paged_att_avg; 630Sstevel@tonic-gate uint64_t col_count; 640Sstevel@tonic-gate int col_fresh; 650Sstevel@tonic-gate struct col *col_next; 660Sstevel@tonic-gate struct col *col_prev; 670Sstevel@tonic-gate lcollection_stat_t col_src_stat; 680Sstevel@tonic-gate lcollection_stat_t col_old_stat; 690Sstevel@tonic-gate } col_t; 700Sstevel@tonic-gate 710Sstevel@tonic-gate static col_t *col_head; 720Sstevel@tonic-gate static int ncol; 730Sstevel@tonic-gate 740Sstevel@tonic-gate static col_t * 750Sstevel@tonic-gate col_find(rcid_t id) 760Sstevel@tonic-gate { 770Sstevel@tonic-gate col_t *col; 780Sstevel@tonic-gate for (col = col_head; col != NULL; col = col->col_next) 793247Sgjelinek if (col->col_id.rcid_type == id.rcid_type && 803247Sgjelinek col->col_id.rcid_val == id.rcid_val) 810Sstevel@tonic-gate return (col); 820Sstevel@tonic-gate return (NULL); 830Sstevel@tonic-gate } 840Sstevel@tonic-gate 850Sstevel@tonic-gate static col_t * 860Sstevel@tonic-gate col_insert(rcid_t id) 870Sstevel@tonic-gate { 880Sstevel@tonic-gate col_t *new_col; 890Sstevel@tonic-gate 900Sstevel@tonic-gate new_col = malloc(sizeof (col_t)); 910Sstevel@tonic-gate if (new_col == NULL) { 920Sstevel@tonic-gate (void) fprintf(stderr, gettext("rcapstat: malloc() failed\n")); 930Sstevel@tonic-gate exit(E_ERROR); 940Sstevel@tonic-gate } 950Sstevel@tonic-gate (void) memset(new_col, 0, sizeof (col_t)); 960Sstevel@tonic-gate new_col->col_next = col_head; 970Sstevel@tonic-gate new_col->col_id = id; 980Sstevel@tonic-gate if (col_head != NULL) 990Sstevel@tonic-gate col_head->col_prev = new_col; 1000Sstevel@tonic-gate col_head = new_col; 1010Sstevel@tonic-gate ncol++; 1020Sstevel@tonic-gate return (new_col); 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate static void 1060Sstevel@tonic-gate col_remove(col_t *col) 1070Sstevel@tonic-gate { 1080Sstevel@tonic-gate if (col->col_prev != NULL) 1090Sstevel@tonic-gate col->col_prev->col_next = col->col_next; 1100Sstevel@tonic-gate if (col->col_next != NULL) 1110Sstevel@tonic-gate col->col_next->col_prev = col->col_prev; 1120Sstevel@tonic-gate if (col_head == col) 1130Sstevel@tonic-gate col_head = col->col_next; 1140Sstevel@tonic-gate ncol--; 1150Sstevel@tonic-gate free(col); 1160Sstevel@tonic-gate } 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate static void 1190Sstevel@tonic-gate usage() 1200Sstevel@tonic-gate { 1210Sstevel@tonic-gate (void) fprintf(stderr, 1223247Sgjelinek gettext("usage: rcapstat [-g] [-p | -z] [interval [count]]\n")); 1230Sstevel@tonic-gate exit(E_USAGE); 1240Sstevel@tonic-gate } 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate static void 1270Sstevel@tonic-gate format_size(char *str, uint64_t size, int length) 1280Sstevel@tonic-gate { 1290Sstevel@tonic-gate char tag = 'K'; 1300Sstevel@tonic-gate if (size >= 10000) { 1310Sstevel@tonic-gate size = (size + 512) / 1024; 1320Sstevel@tonic-gate tag = 'M'; 1330Sstevel@tonic-gate if (size >= 10000) { 1340Sstevel@tonic-gate size = (size + 512) / 1024; 1350Sstevel@tonic-gate tag = 'G'; 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate } 1380Sstevel@tonic-gate (void) snprintf(str, length, "%4lld%c", size, tag); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate static int 1423247Sgjelinek read_stats(rcid_type_t stat_type) 1430Sstevel@tonic-gate { 1440Sstevel@tonic-gate int fd; 1450Sstevel@tonic-gate int proc_fd; 1460Sstevel@tonic-gate char procfile[20]; 1473247Sgjelinek uint64_t pid; 1480Sstevel@tonic-gate col_t *col, *col_next; 1490Sstevel@tonic-gate lcollection_report_t report; 1500Sstevel@tonic-gate struct stat st; 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate if ((fd = open(STAT_FILE_DEFAULT, O_RDONLY)) < 0) { 1530Sstevel@tonic-gate warn(gettext("rcapd is not active\n")); 1540Sstevel@tonic-gate return (E_ERROR); 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate if (fstat(fd, &st) == 0) 1580Sstevel@tonic-gate stat_mod = st.st_mtime; 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate if (read(fd, &hdr, sizeof (hdr)) != sizeof (hdr)) { 1610Sstevel@tonic-gate (void) fprintf(stderr, 1620Sstevel@tonic-gate gettext("rcapstat: can't read stat file header: %s\n"), 1630Sstevel@tonic-gate strerror(errno)); 1640Sstevel@tonic-gate (void) close(fd); 1650Sstevel@tonic-gate return (E_ERROR); 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate /* 1690Sstevel@tonic-gate * Check if rcapd is running 1700Sstevel@tonic-gate */ 1710Sstevel@tonic-gate pid = hdr.rs_pid; 1723247Sgjelinek (void) snprintf(procfile, 20, "/proc/%lld/psinfo", pid); 1730Sstevel@tonic-gate if ((proc_fd = open(procfile, O_RDONLY)) < 0) { 1740Sstevel@tonic-gate warn(gettext("rcapd is not active\n")); 1750Sstevel@tonic-gate (void) close(fd); 1760Sstevel@tonic-gate return (E_ERROR); 1770Sstevel@tonic-gate } 1780Sstevel@tonic-gate (void) close(proc_fd); 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate (void) strncpy(mode, hdr.rs_mode, RC_MODE_LEN); 1810Sstevel@tonic-gate for (col = col_head; col != NULL; col = col->col_next) { 1820Sstevel@tonic-gate col->col_fresh = 0; 1830Sstevel@tonic-gate col->col_paged_eff = 0; 1840Sstevel@tonic-gate col->col_paged_att = 0; 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate while (read(fd, &report, sizeof (report)) == sizeof (report)) { 1883247Sgjelinek if (report.lcol_id.rcid_type != stat_type) 1893247Sgjelinek continue; 1903247Sgjelinek 1910Sstevel@tonic-gate col = col_find(report.lcol_id); 1920Sstevel@tonic-gate if (col == NULL) { 1930Sstevel@tonic-gate col = col_insert(report.lcol_id); 1940Sstevel@tonic-gate col->col_paged_eff_old = col->col_paged_eff = 1950Sstevel@tonic-gate report.lcol_stat.lcols_pg_eff; 1960Sstevel@tonic-gate col->col_paged_att_old = col->col_paged_att = 1970Sstevel@tonic-gate report.lcol_stat.lcols_pg_att; 1980Sstevel@tonic-gate col->col_count = 0; 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate (void) strncpy(col->col_name, report.lcol_name, LC_NAME_LEN); 2010Sstevel@tonic-gate col->col_vmsize = report.lcol_image_size; 2020Sstevel@tonic-gate col->col_rsssize = report.lcol_rss; 2030Sstevel@tonic-gate col->col_rsslimit = report.lcol_rss_cap; 2040Sstevel@tonic-gate col->col_fresh = 1; 2050Sstevel@tonic-gate if (report.lcol_stat.lcols_pg_eff > col->col_paged_eff_old) { 2060Sstevel@tonic-gate col->col_paged_eff = 2070Sstevel@tonic-gate report.lcol_stat.lcols_pg_eff - 2080Sstevel@tonic-gate col->col_paged_eff_old; 2090Sstevel@tonic-gate if (report.lcol_stat.lcols_scan_count > col->col_count) 2100Sstevel@tonic-gate col->col_paged_eff_avg = 2110Sstevel@tonic-gate col->col_paged_eff / 2120Sstevel@tonic-gate (report.lcol_stat.lcols_scan_count - 2130Sstevel@tonic-gate col->col_count); 2140Sstevel@tonic-gate } else { 2150Sstevel@tonic-gate col->col_paged_eff_avg = 0; 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate if (report.lcol_stat.lcols_pg_att > col->col_paged_att_old) { 2180Sstevel@tonic-gate col->col_paged_att = 2190Sstevel@tonic-gate report.lcol_stat.lcols_pg_att - 2200Sstevel@tonic-gate col->col_paged_att_old; 2210Sstevel@tonic-gate if (report.lcol_stat.lcols_scan_count > col->col_count) 2220Sstevel@tonic-gate col->col_paged_att_avg = 2230Sstevel@tonic-gate col->col_paged_att / 2240Sstevel@tonic-gate (report.lcol_stat.lcols_scan_count - 2250Sstevel@tonic-gate col->col_count); 2260Sstevel@tonic-gate } else { 2270Sstevel@tonic-gate col->col_paged_att_avg = 0; 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate col->col_paged_eff_old = report.lcol_stat.lcols_pg_eff; 2300Sstevel@tonic-gate col->col_paged_att_old = report.lcol_stat.lcols_pg_att; 2310Sstevel@tonic-gate col->col_nproc = 2320Sstevel@tonic-gate report.lcol_stat.lcols_proc_in - 2330Sstevel@tonic-gate report.lcol_stat.lcols_proc_out; 2340Sstevel@tonic-gate col->col_count = report.lcol_stat.lcols_scan_count; 2350Sstevel@tonic-gate col->col_src_stat = report.lcol_stat; 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate /* 2390Sstevel@tonic-gate * Remove stale data 2400Sstevel@tonic-gate */ 2410Sstevel@tonic-gate col = col_head; 2420Sstevel@tonic-gate while (col != NULL) { 2430Sstevel@tonic-gate col_next = col->col_next; 2440Sstevel@tonic-gate if (col->col_fresh == 0) 2450Sstevel@tonic-gate col_remove(col); 2460Sstevel@tonic-gate col = col_next; 2470Sstevel@tonic-gate } 2480Sstevel@tonic-gate (void) close(fd); 2490Sstevel@tonic-gate return (E_SUCCESS); 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate /* 2530Sstevel@tonic-gate * Print each collection's interval statistics. 2540Sstevel@tonic-gate */ 2550Sstevel@tonic-gate /*ARGSUSED*/ 2560Sstevel@tonic-gate static void 2570Sstevel@tonic-gate print_unformatted_stats(void) 2580Sstevel@tonic-gate { 2590Sstevel@tonic-gate col_t *col; 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate #define DELTA(field) \ 2620Sstevel@tonic-gate (col->col_src_stat.field - col->col_old_stat.field) 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate col = col_head; 2650Sstevel@tonic-gate while (col != NULL) { 2660Sstevel@tonic-gate if (bcmp(&col->col_src_stat, &col->col_old_stat, 2670Sstevel@tonic-gate sizeof (col->col_src_stat)) == 0) { 2680Sstevel@tonic-gate col = col->col_next; 2690Sstevel@tonic-gate continue; 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate (void) printf("%s %s status: succeeded/attempted (k): " 2720Sstevel@tonic-gate "%llu/%llu, ineffective/scans/unenforced/samplings: " 2730Sstevel@tonic-gate "%llu/%llu/%llu/%llu, RSS min/max (k): %llu/%llu, cap %llu " 2740Sstevel@tonic-gate "kB, processes/thpt: %llu/%llu, %llu scans over %lld ms\n", 2750Sstevel@tonic-gate mode, col->col_name, DELTA(lcols_pg_eff), 2760Sstevel@tonic-gate DELTA(lcols_pg_att), DELTA(lcols_scan_ineffective), 2770Sstevel@tonic-gate DELTA(lcols_scan), DELTA(lcols_unenforced_cap), 2780Sstevel@tonic-gate DELTA(lcols_rss_sample), col->col_src_stat.lcols_min_rss, 2790Sstevel@tonic-gate col->col_src_stat.lcols_max_rss, col->col_rsslimit, 2800Sstevel@tonic-gate (col->col_src_stat.lcols_proc_in - 2810Sstevel@tonic-gate col->col_old_stat.lcols_proc_out), DELTA(lcols_proc_out), 2820Sstevel@tonic-gate DELTA(lcols_scan_count), DELTA(lcols_scan_time_complete) / 2830Sstevel@tonic-gate (NANOSEC / MILLISEC)); 2840Sstevel@tonic-gate col->col_old_stat = col->col_src_stat; 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate col = col->col_next; 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate if (global) 2900Sstevel@tonic-gate (void) printf(gettext("physical memory utilization: %3u%% " 2910Sstevel@tonic-gate "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur, 2920Sstevel@tonic-gate hdr.rs_pressure_cap); 2930Sstevel@tonic-gate #undef DELTA 2940Sstevel@tonic-gate } 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate static void 2973247Sgjelinek print_stats(rcid_type_t stat_type) 2980Sstevel@tonic-gate { 2990Sstevel@tonic-gate col_t *col; 3000Sstevel@tonic-gate char size[6]; 3010Sstevel@tonic-gate char limit[6]; 3020Sstevel@tonic-gate char rss[6]; 3033247Sgjelinek char nproc[6]; 3040Sstevel@tonic-gate char paged_att[6]; 3050Sstevel@tonic-gate char paged_eff[6]; 3060Sstevel@tonic-gate char paged_att_avg[6]; 3070Sstevel@tonic-gate char paged_eff_avg[6]; 3080Sstevel@tonic-gate static int count = 0; 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate /* 3110Sstevel@tonic-gate * Print a header once every 20 times if we're only displaying reports 3120Sstevel@tonic-gate * for one collection (10 times if -g is used). Print a header every 3130Sstevel@tonic-gate * interval otherwise. 3140Sstevel@tonic-gate */ 3150Sstevel@tonic-gate if (count == 0 || ncol != 1) 3160Sstevel@tonic-gate (void) printf("%6s %-15s %5s %5s %5s %5s %5s %5s %5s %5s\n", 3173247Sgjelinek "id", (stat_type == RCIDT_PROJECT ? "project" : "zone"), 3183247Sgjelinek "nproc", "vm", "rss", "cap", 3190Sstevel@tonic-gate "at", "avgat", "pg", "avgpg"); 3200Sstevel@tonic-gate if (++count >= 20 || (count >= 10 && global != 0) || ncol != 1) 3210Sstevel@tonic-gate count = 0; 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate for (col = col_head; col != NULL; col = col->col_next) { 3243247Sgjelinek if (col->col_id.rcid_type != stat_type) 3253247Sgjelinek continue; 3263247Sgjelinek 3273247Sgjelinek if (col->col_paged_att == 0) 328*4131Stn143363 (void) strlcpy(nproc, "-", sizeof (nproc)); 3293247Sgjelinek else 3303247Sgjelinek (void) snprintf(nproc, sizeof (nproc), "%lld", 3313247Sgjelinek col->col_nproc); 3320Sstevel@tonic-gate format_size(size, col->col_vmsize, 6); 3330Sstevel@tonic-gate format_size(rss, col->col_rsssize, 6); 3340Sstevel@tonic-gate format_size(limit, col->col_rsslimit, 6); 3350Sstevel@tonic-gate format_size(paged_att, col->col_paged_att, 6); 3360Sstevel@tonic-gate format_size(paged_eff, col->col_paged_eff, 6); 3370Sstevel@tonic-gate format_size(paged_att_avg, col->col_paged_att_avg, 6); 3380Sstevel@tonic-gate format_size(paged_eff_avg, col->col_paged_eff_avg, 6); 3393247Sgjelinek (void) printf("%6lld %-15s %5s %5s %5s %5s %5s %5s %5s %5s\n", 3403247Sgjelinek col->col_id.rcid_val, col->col_name, 3413247Sgjelinek nproc, 3420Sstevel@tonic-gate size, rss, limit, 3430Sstevel@tonic-gate paged_att, paged_att_avg, 3440Sstevel@tonic-gate paged_eff, paged_eff_avg); 3450Sstevel@tonic-gate } 3460Sstevel@tonic-gate if (global) 3470Sstevel@tonic-gate (void) printf(gettext("physical memory utilization: %3u%% " 3480Sstevel@tonic-gate "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur, 3490Sstevel@tonic-gate hdr.rs_pressure_cap); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate int 3530Sstevel@tonic-gate main(int argc, char *argv[]) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate int interval = 5; 3560Sstevel@tonic-gate int count; 3570Sstevel@tonic-gate int always = 1; 3580Sstevel@tonic-gate int opt; 3593247Sgjelinek int projects = 0; 3603247Sgjelinek int zones = 0; 3613247Sgjelinek /* project reporting is the default if no option is specified */ 3623247Sgjelinek rcid_type_t stat_type = RCIDT_PROJECT; 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 3650Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 3660Sstevel@tonic-gate (void) setprogname("rcapstat"); 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate global = unformatted = 0; 3693247Sgjelinek while ((opt = getopt(argc, argv, "gpuz")) != (int)EOF) { 3700Sstevel@tonic-gate switch (opt) { 3710Sstevel@tonic-gate case 'g': 3720Sstevel@tonic-gate global = 1; 3730Sstevel@tonic-gate break; 3743247Sgjelinek case 'p': 3753247Sgjelinek projects = 1; 3763247Sgjelinek stat_type = RCIDT_PROJECT; 3773247Sgjelinek break; 3780Sstevel@tonic-gate case 'u': 3790Sstevel@tonic-gate unformatted = 1; 3800Sstevel@tonic-gate break; 3813247Sgjelinek case 'z': 3823247Sgjelinek stat_type = RCIDT_ZONE; 3833247Sgjelinek zones = 1; 3843247Sgjelinek break; 3850Sstevel@tonic-gate default: 3860Sstevel@tonic-gate usage(); 3870Sstevel@tonic-gate } 3880Sstevel@tonic-gate } 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate if (argc > optind) 3910Sstevel@tonic-gate if ((interval = xatoi(argv[optind++])) <= 0) 3920Sstevel@tonic-gate die(gettext("invalid interval specified\n")); 3930Sstevel@tonic-gate if (argc > optind) { 3940Sstevel@tonic-gate if ((count = xatoi(argv[optind++])) <= 0) 3950Sstevel@tonic-gate die(gettext("invalid count specified\n")); 3960Sstevel@tonic-gate always = 0; 3970Sstevel@tonic-gate } 3983247Sgjelinek if (argc > optind || (projects > 0 && zones > 0)) 3990Sstevel@tonic-gate usage(); 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate while (always || count-- > 0) { 4023247Sgjelinek if (read_stats(stat_type) != E_SUCCESS) 4030Sstevel@tonic-gate return (E_ERROR); 4040Sstevel@tonic-gate if (!unformatted) { 4053247Sgjelinek print_stats(stat_type); 4063247Sgjelinek (void) fflush(stdout); 4070Sstevel@tonic-gate if (count || always) 4080Sstevel@tonic-gate (void) sleep(interval); 4090Sstevel@tonic-gate } else { 4100Sstevel@tonic-gate struct stat st; 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate print_unformatted_stats(); 4133247Sgjelinek (void) fflush(stdout); 4140Sstevel@tonic-gate while (stat(STAT_FILE_DEFAULT, &st) == 0 && 4150Sstevel@tonic-gate st.st_mtime == stat_mod) 416*4131Stn143363 (void) usleep((useconds_t)(0.2 * MICROSEC)); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate return (E_SUCCESS); 4210Sstevel@tonic-gate } 422