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 5*26fd7700SKrishnendu Sadhukhan - Sun Microsystems * Common Development and Distribution License (the "License"). 6*26fd7700SKrishnendu Sadhukhan - Sun Microsystems * 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 */ 21d9638e54Smws 227c478bd9Sstevel@tonic-gate /* 23*26fd7700SKrishnendu Sadhukhan - Sun Microsystems * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <fm/fmd_adm.h> 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <strings.h> 307c478bd9Sstevel@tonic-gate #include <limits.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <stdarg.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <errno.h> 357c478bd9Sstevel@tonic-gate #include <poll.h> 36*26fd7700SKrishnendu Sadhukhan - Sun Microsystems #include <locale.h> 37*26fd7700SKrishnendu Sadhukhan - Sun Microsystems 38*26fd7700SKrishnendu Sadhukhan - Sun Microsystems #include "statcommon.h" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #define FMSTAT_EXIT_SUCCESS 0 417c478bd9Sstevel@tonic-gate #define FMSTAT_EXIT_ERROR 1 427c478bd9Sstevel@tonic-gate #define FMSTAT_EXIT_USAGE 2 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate static const struct stats { 45d9638e54Smws fmd_stat_t module; 46d9638e54Smws fmd_stat_t authority; 47d9638e54Smws fmd_stat_t state; 487c478bd9Sstevel@tonic-gate fmd_stat_t loadtime; 497c478bd9Sstevel@tonic-gate fmd_stat_t snaptime; 50d9638e54Smws fmd_stat_t received; 51d9638e54Smws fmd_stat_t discarded; 52d9638e54Smws fmd_stat_t retried; 53d9638e54Smws fmd_stat_t replayed; 54d9638e54Smws fmd_stat_t lost; 557c478bd9Sstevel@tonic-gate fmd_stat_t dispatched; 567c478bd9Sstevel@tonic-gate fmd_stat_t dequeued; 577c478bd9Sstevel@tonic-gate fmd_stat_t prdequeued; 587c478bd9Sstevel@tonic-gate fmd_stat_t accepted; 597c478bd9Sstevel@tonic-gate fmd_stat_t memtotal; 607c478bd9Sstevel@tonic-gate fmd_stat_t buftotal; 617c478bd9Sstevel@tonic-gate fmd_stat_t caseopen; 627c478bd9Sstevel@tonic-gate fmd_stat_t casesolved; 637c478bd9Sstevel@tonic-gate fmd_stat_t wcnt; 647c478bd9Sstevel@tonic-gate fmd_stat_t wtime; 657c478bd9Sstevel@tonic-gate fmd_stat_t wlentime; 667c478bd9Sstevel@tonic-gate fmd_stat_t wlastupdate; 677c478bd9Sstevel@tonic-gate fmd_stat_t dtime; 687c478bd9Sstevel@tonic-gate fmd_stat_t dlastupdate; 697c478bd9Sstevel@tonic-gate } stats_template = { 70d9638e54Smws { "module", FMD_TYPE_STRING }, 71d9638e54Smws { "authority", FMD_TYPE_STRING }, 72d9638e54Smws { "state", FMD_TYPE_STRING }, 73d9638e54Smws { "loadtime", FMD_TYPE_TIME }, 74d9638e54Smws { "snaptime", FMD_TYPE_TIME }, 75d9638e54Smws { "received", FMD_TYPE_UINT64 }, 76d9638e54Smws { "discarded", FMD_TYPE_UINT64 }, 77d9638e54Smws { "retried", FMD_TYPE_UINT64 }, 78d9638e54Smws { "replayed", FMD_TYPE_UINT64 }, 79d9638e54Smws { "lost", FMD_TYPE_UINT64 }, 80d9638e54Smws { "dispatched", FMD_TYPE_UINT64 }, 81d9638e54Smws { "dequeued", FMD_TYPE_UINT64 }, 82d9638e54Smws { "prdequeued", FMD_TYPE_UINT64 }, 83d9638e54Smws { "accepted", FMD_TYPE_UINT64 }, 84d9638e54Smws { "memtotal", FMD_TYPE_SIZE }, 85d9638e54Smws { "buftotal", FMD_TYPE_SIZE }, 86d9638e54Smws { "caseopen", FMD_TYPE_UINT64 }, 87d9638e54Smws { "casesolved", FMD_TYPE_UINT64 }, 88d9638e54Smws { "wcnt", FMD_TYPE_UINT32 }, 89d9638e54Smws { "wtime", FMD_TYPE_TIME }, 90d9638e54Smws { "wlentime", FMD_TYPE_TIME }, 91d9638e54Smws { "wlastupdate", FMD_TYPE_TIME }, 92d9638e54Smws { "dtime", FMD_TYPE_TIME }, 93d9638e54Smws { "dlastupdate", FMD_TYPE_TIME }, 947c478bd9Sstevel@tonic-gate }; 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate static const char *g_pname; 977c478bd9Sstevel@tonic-gate static fmd_adm_t *g_adm; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate static struct modstats { 1007c478bd9Sstevel@tonic-gate char *m_name; 1017c478bd9Sstevel@tonic-gate struct modstats *m_next; 1027c478bd9Sstevel@tonic-gate struct stats m_stbuf[2]; 1037c478bd9Sstevel@tonic-gate int m_stidx; 104d9638e54Smws int m_id; 105d9638e54Smws struct stats *m_old; 106d9638e54Smws struct stats *m_new; 107d9638e54Smws double m_wait; 108d9638e54Smws double m_svc; 109d9638e54Smws double m_pct_b; 110d9638e54Smws double m_pct_w; 1117c478bd9Sstevel@tonic-gate } *g_mods; 1127c478bd9Sstevel@tonic-gate 113*26fd7700SKrishnendu Sadhukhan - Sun Microsystems static uint_t timestamp_fmt = NODATE; 114*26fd7700SKrishnendu Sadhukhan - Sun Microsystems 115*26fd7700SKrishnendu Sadhukhan - Sun Microsystems #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 116*26fd7700SKrishnendu Sadhukhan - Sun Microsystems #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */ 117*26fd7700SKrishnendu Sadhukhan - Sun Microsystems #endif 118*26fd7700SKrishnendu Sadhukhan - Sun Microsystems 1197c478bd9Sstevel@tonic-gate static void 1207c478bd9Sstevel@tonic-gate vwarn(const char *format, va_list ap) 1217c478bd9Sstevel@tonic-gate { 1227c478bd9Sstevel@tonic-gate int err = errno; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", g_pname); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate if (format != NULL) 1277c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, format, ap); 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate errno = err; /* restore errno for fmd_adm_errmsg() */ 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate if (format == NULL) 1327c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s\n", fmd_adm_errmsg(g_adm)); 1337c478bd9Sstevel@tonic-gate else if (strchr(format, '\n') == NULL) 1347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ": %s\n", fmd_adm_errmsg(g_adm)); 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 1387c478bd9Sstevel@tonic-gate void 1397c478bd9Sstevel@tonic-gate warn(const char *format, ...) 1407c478bd9Sstevel@tonic-gate { 1417c478bd9Sstevel@tonic-gate va_list ap; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate va_start(ap, format); 1447c478bd9Sstevel@tonic-gate vwarn(format, ap); 1457c478bd9Sstevel@tonic-gate va_end(ap); 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 1497c478bd9Sstevel@tonic-gate void 1507c478bd9Sstevel@tonic-gate die(const char *format, ...) 1517c478bd9Sstevel@tonic-gate { 1527c478bd9Sstevel@tonic-gate va_list ap; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate va_start(ap, format); 1557c478bd9Sstevel@tonic-gate vwarn(format, ap); 1567c478bd9Sstevel@tonic-gate va_end(ap); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate fmd_adm_close(g_adm); 1597c478bd9Sstevel@tonic-gate exit(FMSTAT_EXIT_ERROR); 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate static char * 1637c478bd9Sstevel@tonic-gate time2str(char *buf, size_t len, uint64_t time) 1647c478bd9Sstevel@tonic-gate { 1657c478bd9Sstevel@tonic-gate static const struct unit { 1667c478bd9Sstevel@tonic-gate const char *u_name; 1677c478bd9Sstevel@tonic-gate hrtime_t u_mul; 1687c478bd9Sstevel@tonic-gate } units[] = { 1697c478bd9Sstevel@tonic-gate { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 1707c478bd9Sstevel@tonic-gate { "h", NANOSEC * (hrtime_t)(60 * 60) }, 1717c478bd9Sstevel@tonic-gate { "m", NANOSEC * (hrtime_t)60 }, 1727c478bd9Sstevel@tonic-gate { "s", NANOSEC / SEC }, 1737c478bd9Sstevel@tonic-gate { "ms", NANOSEC / MILLISEC }, 1747c478bd9Sstevel@tonic-gate { "us", NANOSEC / MICROSEC }, 1757c478bd9Sstevel@tonic-gate { "ns", NANOSEC / NANOSEC }, 1767c478bd9Sstevel@tonic-gate }; 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate const struct unit *up; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate for (up = units; time % up->u_mul != 0; up++) 1817c478bd9Sstevel@tonic-gate continue; /* find largest unit of which 'time' is a multiple */ 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate (void) snprintf(buf, len, "%llu%s", time / up->u_mul, up->u_name); 1847c478bd9Sstevel@tonic-gate return (buf); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate static char * 1887c478bd9Sstevel@tonic-gate size2str(char *buf, size_t len, uint64_t size) 1897c478bd9Sstevel@tonic-gate { 1907c478bd9Sstevel@tonic-gate static const char units[] = "bKMGTPE"; 1917c478bd9Sstevel@tonic-gate const uint64_t scale = 1024; 1927c478bd9Sstevel@tonic-gate const char *up = units; 1937c478bd9Sstevel@tonic-gate uint64_t osize = 0; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate /* 1967c478bd9Sstevel@tonic-gate * Convert the input size to a round number of the appropriately 1977c478bd9Sstevel@tonic-gate * scaled units (saved in 'size') and a remainder (saved in 'osize'). 1987c478bd9Sstevel@tonic-gate */ 1997c478bd9Sstevel@tonic-gate while (size >= scale && up < (units + sizeof (units) - 2)) { 2007c478bd9Sstevel@tonic-gate up++; 2017c478bd9Sstevel@tonic-gate osize = size; 2027c478bd9Sstevel@tonic-gate size = (size + (scale / 2)) / scale; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate /* 2067c478bd9Sstevel@tonic-gate * Format the result using at most one decimal place and the unit 2077c478bd9Sstevel@tonic-gate * depending upon the amount of remainder (same as df -h algorithm). 2087c478bd9Sstevel@tonic-gate */ 2097c478bd9Sstevel@tonic-gate if (osize != 0 && (osize / scale) < 10) 2107c478bd9Sstevel@tonic-gate (void) snprintf(buf, len, "%.1f%c", (float)osize / scale, *up); 2117c478bd9Sstevel@tonic-gate else if (size != 0) 2127c478bd9Sstevel@tonic-gate (void) snprintf(buf, len, "%llu%c", size, *up); 2137c478bd9Sstevel@tonic-gate else 2147c478bd9Sstevel@tonic-gate (void) snprintf(buf, len, "0"); 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate return (buf); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate static uint64_t 2207c478bd9Sstevel@tonic-gate u64delta(uint64_t old, uint64_t new) 2217c478bd9Sstevel@tonic-gate { 2227c478bd9Sstevel@tonic-gate return (new >= old ? (new - old) : ((UINT64_MAX - old) + new + 1)); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 225d9638e54Smws static struct modstats * 226d9638e54Smws modstat_create(const char *name, id_t id) 227d9638e54Smws { 228d9638e54Smws struct modstats *mp = malloc(sizeof (struct modstats)); 229d9638e54Smws 230d9638e54Smws if (mp == NULL) 231d9638e54Smws return (NULL); 232d9638e54Smws 233d9638e54Smws bzero(mp, sizeof (struct modstats)); 234d9638e54Smws 235d9638e54Smws if (name != NULL && (mp->m_name = strdup(name)) == NULL) { 236d9638e54Smws free(mp); 237d9638e54Smws return (NULL); 238d9638e54Smws } 239d9638e54Smws 240d9638e54Smws mp->m_id = id; 241d9638e54Smws mp->m_next = g_mods; 242d9638e54Smws g_mods = mp; 243d9638e54Smws return (mp); 244d9638e54Smws } 245d9638e54Smws 246d9638e54Smws /* 247d9638e54Smws * Given a statistics buffer containing event queue statistics, compute the 248d9638e54Smws * common queue statistics for the given module and store the results in 'mp'. 249d9638e54Smws * We set m_new and m_old for the caller, and store the compute values of 250d9638e54Smws * m_svc, m_wait, m_pct_w, and m_pct_b there as well. The caller must not free 251d9638e54Smws * 'ams' until after using the results as m_new may contain pointers to it. 252d9638e54Smws */ 253d9638e54Smws static void 254d9638e54Smws modstat_compute(struct modstats *mp, fmd_adm_stats_t *ams) 2557c478bd9Sstevel@tonic-gate { 2567c478bd9Sstevel@tonic-gate static fmd_stat_t *t_beg = (fmd_stat_t *)(&stats_template + 0); 2577c478bd9Sstevel@tonic-gate static fmd_stat_t *t_end = (fmd_stat_t *)(&stats_template + 1); 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate struct stats *old, *new; 260d9638e54Smws fmd_stat_t *tsp, *nsp, *sp; 261d9638e54Smws double elapsed, avg_w, avg_d; 2627c478bd9Sstevel@tonic-gate uint64_t delta; 2637c478bd9Sstevel@tonic-gate 264d9638e54Smws old = mp->m_old = &mp->m_stbuf[mp->m_stidx]; 2657c478bd9Sstevel@tonic-gate mp->m_stidx = 1 - mp->m_stidx; 266d9638e54Smws new = mp->m_new = &mp->m_stbuf[mp->m_stidx]; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* 2697c478bd9Sstevel@tonic-gate * The statistics can come in any order; we compare each one to the 2707c478bd9Sstevel@tonic-gate * template of statistics of interest, find the matching ones, and copy 2717c478bd9Sstevel@tonic-gate * their values into the appropriate slot of the 'new' stats. 2727c478bd9Sstevel@tonic-gate */ 273d9638e54Smws for (nsp = ams->ams_buf; nsp < ams->ams_buf + ams->ams_len; nsp++) { 2747c478bd9Sstevel@tonic-gate for (tsp = t_beg; tsp < t_end; tsp++) { 275d9638e54Smws const char *p = strrchr(nsp->fmds_name, '.'); 276d9638e54Smws 277d9638e54Smws /* 278d9638e54Smws * The fmd queue stats can either be named fmd.<name> 279d9638e54Smws * or fmd.xprt.%u.<name> depending on whether we're 280d9638e54Smws * looking at the module queue or the transport queue. 281d9638e54Smws * So we match using the patterns fmd.* and *.<name> 282d9638e54Smws * and store only the value of <name> in stats_template. 283d9638e54Smws */ 284d9638e54Smws if (p == NULL || strcmp(p + 1, tsp->fmds_name) != 0 || 285d9638e54Smws strncmp(nsp->fmds_name, "fmd.", 4) != 0) 286d9638e54Smws continue; /* continue until we match the stat */ 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate if (tsp->fmds_type != nsp->fmds_type) { 2897c478bd9Sstevel@tonic-gate warn("%s has unexpected type (%u != %u)\n", 290d9638e54Smws nsp->fmds_name, tsp->fmds_type, 2917c478bd9Sstevel@tonic-gate nsp->fmds_type); 2927c478bd9Sstevel@tonic-gate } else { 2937c478bd9Sstevel@tonic-gate sp = (fmd_stat_t *)new + (tsp - t_beg); 2947c478bd9Sstevel@tonic-gate sp->fmds_value = nsp->fmds_value; 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate /* 3007c478bd9Sstevel@tonic-gate * Compute the elapsed time by taking the delta between 'snaptime', or 3017c478bd9Sstevel@tonic-gate * or between snaptime and loadtime if there is no previous snapshot. 3027c478bd9Sstevel@tonic-gate * If delta is zero, set it to 1sec so we don't divide by zero later. 3037c478bd9Sstevel@tonic-gate */ 3047c478bd9Sstevel@tonic-gate delta = u64delta(old->snaptime.fmds_value.ui64 ? 3057c478bd9Sstevel@tonic-gate old->snaptime.fmds_value.ui64 : old->loadtime.fmds_value.ui64, 3067c478bd9Sstevel@tonic-gate new->snaptime.fmds_value.ui64); 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate elapsed = delta ? (double)delta : (double)NANOSEC; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Compute average wait queue len by taking the delta in the wait queue 3127c478bd9Sstevel@tonic-gate * len * time products (wlentime stat) and dividing by the elapsed time. 3137c478bd9Sstevel@tonic-gate */ 3147c478bd9Sstevel@tonic-gate delta = u64delta(old->wlentime.fmds_value.ui64, 3157c478bd9Sstevel@tonic-gate new->wlentime.fmds_value.ui64); 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if (delta != 0) 318d9638e54Smws mp->m_wait = (double)delta / elapsed; 3197c478bd9Sstevel@tonic-gate else 320d9638e54Smws mp->m_wait = 0.0; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate /* 3237c478bd9Sstevel@tonic-gate * Compute average wait time by taking the delta in the wait queue time 3247c478bd9Sstevel@tonic-gate * (wtime) and dividing by the delta in the number of dispatches. 3257c478bd9Sstevel@tonic-gate */ 3267c478bd9Sstevel@tonic-gate delta = u64delta(old->dispatched.fmds_value.ui64, 3277c478bd9Sstevel@tonic-gate new->dispatched.fmds_value.ui64); 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate if (delta != 0) { 3307c478bd9Sstevel@tonic-gate avg_w = (double)u64delta(old->wtime.fmds_value.ui64, 3317c478bd9Sstevel@tonic-gate new->wtime.fmds_value.ui64) / (double)delta; 3327c478bd9Sstevel@tonic-gate } else 3337c478bd9Sstevel@tonic-gate avg_w = 0.0; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * Compute average dispatch time by taking the delta in the dispatch 3377c478bd9Sstevel@tonic-gate * time (dtime) and dividing by the delta in the number of dequeues. 3387c478bd9Sstevel@tonic-gate */ 3397c478bd9Sstevel@tonic-gate delta = u64delta(old->dequeued.fmds_value.ui64, 3407c478bd9Sstevel@tonic-gate new->dequeued.fmds_value.ui64); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate if (delta != 0) { 3437c478bd9Sstevel@tonic-gate avg_d = (double)u64delta(old->dtime.fmds_value.ui64, 3447c478bd9Sstevel@tonic-gate new->dtime.fmds_value.ui64) / (double)delta; 3457c478bd9Sstevel@tonic-gate } else 3467c478bd9Sstevel@tonic-gate avg_d = 0.0; 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate /* 3497c478bd9Sstevel@tonic-gate * Finally compute the average overall service time by adding together 3507c478bd9Sstevel@tonic-gate * the average wait and dispatch times and converting to milliseconds. 3517c478bd9Sstevel@tonic-gate */ 352d9638e54Smws mp->m_svc = ((avg_w + avg_d) * (double)MILLISEC) / (double)NANOSEC; 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate /* 3557c478bd9Sstevel@tonic-gate * Compute the %wait and %busy times by taking the delta in wait and 3567c478bd9Sstevel@tonic-gate * busy times, dividing by the elapsed time, and multiplying by 100. 3577c478bd9Sstevel@tonic-gate */ 3587c478bd9Sstevel@tonic-gate delta = u64delta(old->wtime.fmds_value.ui64, 3597c478bd9Sstevel@tonic-gate new->wtime.fmds_value.ui64); 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate if (delta != 0) 362d9638e54Smws mp->m_pct_w = ((double)delta / elapsed) * 100.0; 3637c478bd9Sstevel@tonic-gate else 364d9638e54Smws mp->m_pct_w = 0.0; 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate delta = u64delta(old->dtime.fmds_value.ui64, 3677c478bd9Sstevel@tonic-gate new->dtime.fmds_value.ui64); 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate if (delta != 0) 370d9638e54Smws mp->m_pct_b = ((double)delta / elapsed) * 100.0; 3717c478bd9Sstevel@tonic-gate else 372d9638e54Smws mp->m_pct_b = 0.0; 373d9638e54Smws } 3747c478bd9Sstevel@tonic-gate 375d9638e54Smws /*ARGSUSED*/ 376d9638e54Smws static int 377d9638e54Smws stat_one_xprt(id_t id, void *ignored) 378d9638e54Smws { 379d9638e54Smws fmd_adm_stats_t ams; 380d9638e54Smws struct modstats *mp; 381d9638e54Smws 382d9638e54Smws if (fmd_adm_xprt_stats(g_adm, id, &ams) != 0) { 383d9638e54Smws warn("failed to retrieve statistics for transport %d", (int)id); 384d9638e54Smws return (0); /* continue on to the next transport */ 385d9638e54Smws } 386d9638e54Smws 387d9638e54Smws for (mp = g_mods; mp != NULL; mp = mp->m_next) { 388d9638e54Smws if (mp->m_id == id) 389d9638e54Smws break; 390d9638e54Smws } 391d9638e54Smws 392d9638e54Smws if (mp == NULL && (mp = modstat_create(NULL, id)) == NULL) { 393d9638e54Smws warn("failed to allocate memory for transport %d", (int)id); 394d9638e54Smws (void) fmd_adm_stats_free(g_adm, &ams); 395d9638e54Smws return (0); 396d9638e54Smws } 397d9638e54Smws 398d9638e54Smws modstat_compute(mp, &ams); 399d9638e54Smws 400d9638e54Smws (void) printf("%3d %5s %7llu %7llu %7llu %7llu " 401d9638e54Smws "%4.1f %6.1f %3.0f %3.0f %s\n", (int)id, 402d9638e54Smws mp->m_new->state.fmds_value.str, 403d9638e54Smws u64delta(mp->m_old->prdequeued.fmds_value.ui64, 404d9638e54Smws mp->m_new->prdequeued.fmds_value.ui64), 405d9638e54Smws u64delta(mp->m_old->received.fmds_value.ui64, 406d9638e54Smws mp->m_new->received.fmds_value.ui64), 407d9638e54Smws u64delta(mp->m_old->discarded.fmds_value.ui64, 408d9638e54Smws mp->m_new->discarded.fmds_value.ui64), 409d9638e54Smws u64delta(mp->m_old->lost.fmds_value.ui64, 410d9638e54Smws mp->m_new->lost.fmds_value.ui64), 411d9638e54Smws mp->m_wait, mp->m_svc, mp->m_pct_w, mp->m_pct_b, 412d9638e54Smws mp->m_new->module.fmds_value.str); 413d9638e54Smws 414d9638e54Smws (void) fmd_adm_stats_free(g_adm, &ams); 415d9638e54Smws return (0); 416d9638e54Smws } 417d9638e54Smws 418d9638e54Smws static void 419d9638e54Smws stat_xprt(void) 420d9638e54Smws { 421d9638e54Smws (void) printf("%3s %5s %7s %7s %7s %7s %4s %6s %3s %3s %s\n", 422d9638e54Smws "id", "state", "ev_send", "ev_recv", "ev_drop", "ev_lost", 423d9638e54Smws "wait", "svc_t", "%w", "%b", "module"); 424d9638e54Smws 425d9638e54Smws if (fmd_adm_xprt_iter(g_adm, stat_one_xprt, NULL) != 0) 426d9638e54Smws die("failed to retrieve list of transports"); 427d9638e54Smws } 428d9638e54Smws 429d9638e54Smws static int 430d9638e54Smws stat_one_xprt_auth(id_t id, void *arg) 431d9638e54Smws { 432d9638e54Smws const char *module = arg; 433d9638e54Smws fmd_adm_stats_t ams; 434d9638e54Smws struct modstats *mp; 435d9638e54Smws 436d9638e54Smws if (fmd_adm_xprt_stats(g_adm, id, &ams) != 0) { 437d9638e54Smws warn("failed to retrieve statistics for transport %d", (int)id); 438d9638e54Smws return (0); /* continue on to the next transport */ 439d9638e54Smws } 440d9638e54Smws 441d9638e54Smws for (mp = g_mods; mp != NULL; mp = mp->m_next) { 442d9638e54Smws if (mp->m_id == id) 443d9638e54Smws break; 444d9638e54Smws } 445d9638e54Smws 446d9638e54Smws if (mp == NULL && (mp = modstat_create(NULL, id)) == NULL) { 447d9638e54Smws warn("failed to allocate memory for transport %d", (int)id); 448d9638e54Smws (void) fmd_adm_stats_free(g_adm, &ams); 449d9638e54Smws return (0); 450d9638e54Smws } 451d9638e54Smws 452d9638e54Smws modstat_compute(mp, &ams); 453d9638e54Smws 454d9638e54Smws if (module == NULL || 455d9638e54Smws strcmp(module, mp->m_new->module.fmds_value.str) == 0) { 456d9638e54Smws (void) printf("%3d %5s %-18s %s\n", (int)id, 457d9638e54Smws mp->m_new->state.fmds_value.str, 458d9638e54Smws mp->m_new->module.fmds_value.str, 459d9638e54Smws mp->m_new->authority.fmds_value.str ? 460d9638e54Smws mp->m_new->authority.fmds_value.str : "-"); 461d9638e54Smws } 462d9638e54Smws 463d9638e54Smws (void) fmd_adm_stats_free(g_adm, &ams); 464d9638e54Smws return (0); 465d9638e54Smws } 466d9638e54Smws 467d9638e54Smws static void 468d9638e54Smws stat_xprt_auth(const char *module) 469d9638e54Smws { 470d9638e54Smws (void) printf("%3s %5s %-18s %s\n", 471d9638e54Smws "id", "state", "module", "authority"); 472d9638e54Smws 473d9638e54Smws if (fmd_adm_xprt_iter(g_adm, stat_one_xprt_auth, (void *)module) != 0) 474d9638e54Smws die("failed to retrieve list of transports"); 475d9638e54Smws } 476d9638e54Smws 477d9638e54Smws /*ARGSUSED*/ 478d9638e54Smws static int 479d9638e54Smws stat_one_fmd(const fmd_adm_modinfo_t *ami, void *ignored) 480d9638e54Smws { 481d9638e54Smws char memsz[8], bufsz[8]; 482d9638e54Smws fmd_adm_stats_t ams; 483d9638e54Smws struct modstats *mp; 484d9638e54Smws 485d9638e54Smws if (fmd_adm_module_stats(g_adm, ami->ami_name, &ams) != 0) { 486d9638e54Smws warn("failed to retrieve statistics for %s", ami->ami_name); 487d9638e54Smws return (0); /* continue on to the next module */ 488d9638e54Smws } 489d9638e54Smws 490d9638e54Smws for (mp = g_mods; mp != NULL; mp = mp->m_next) { 491d9638e54Smws if (strcmp(mp->m_name, ami->ami_name) == 0) 492d9638e54Smws break; 493d9638e54Smws } 494d9638e54Smws 495d9638e54Smws if (mp == NULL && (mp = modstat_create(ami->ami_name, 0)) == NULL) { 496d9638e54Smws warn("failed to allocate memory for %s", ami->ami_name); 497d9638e54Smws (void) fmd_adm_stats_free(g_adm, &ams); 498d9638e54Smws return (0); 499d9638e54Smws } 500d9638e54Smws 501d9638e54Smws modstat_compute(mp, &ams); 502d9638e54Smws 5037c478bd9Sstevel@tonic-gate (void) printf("%-18s %7llu %7llu %4.1f %6.1f %3.0f %3.0f " 5047c478bd9Sstevel@tonic-gate "%5llu %5llu %6s %6s\n", ami->ami_name, 505d9638e54Smws u64delta(mp->m_old->prdequeued.fmds_value.ui64, 506d9638e54Smws mp->m_new->prdequeued.fmds_value.ui64), 507d9638e54Smws u64delta(mp->m_old->accepted.fmds_value.ui64, 508d9638e54Smws mp->m_new->accepted.fmds_value.ui64), 509d9638e54Smws mp->m_wait, mp->m_svc, mp->m_pct_w, mp->m_pct_b, 510d9638e54Smws mp->m_new->caseopen.fmds_value.ui64, 511d9638e54Smws mp->m_new->casesolved.fmds_value.ui64, 512d9638e54Smws size2str(memsz, sizeof (memsz), 513d9638e54Smws mp->m_new->memtotal.fmds_value.ui64), 514d9638e54Smws size2str(bufsz, sizeof (bufsz), 515d9638e54Smws mp->m_new->buftotal.fmds_value.ui64)); 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate (void) fmd_adm_stats_free(g_adm, &ams); 5187c478bd9Sstevel@tonic-gate return (0); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate static void 5227c478bd9Sstevel@tonic-gate stat_fmd(void) 5237c478bd9Sstevel@tonic-gate { 5247c478bd9Sstevel@tonic-gate (void) printf("%-18s %7s %7s %4s %6s %3s %3s %5s %5s %6s %6s\n", 5257c478bd9Sstevel@tonic-gate "module", "ev_recv", "ev_acpt", "wait", "svc_t", "%w", "%b", 5267c478bd9Sstevel@tonic-gate "open", "solve", "memsz", "bufsz"); 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate if (fmd_adm_module_iter(g_adm, stat_one_fmd, NULL) != 0) 5297c478bd9Sstevel@tonic-gate die("failed to retrieve list of modules"); 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate static void 5337c478bd9Sstevel@tonic-gate stat_mod(const char *name, int aflag, int zflag) 5347c478bd9Sstevel@tonic-gate { 5357c478bd9Sstevel@tonic-gate fmd_adm_stats_t ams; 5367c478bd9Sstevel@tonic-gate fmd_stat_t *sp; 5377c478bd9Sstevel@tonic-gate char buf[64]; 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate if (fmd_adm_stats_read(g_adm, name, &ams) != 0) { 5407c478bd9Sstevel@tonic-gate die("failed to retrieve statistics for %s", 5417c478bd9Sstevel@tonic-gate name ? name : "fmd(1M)"); 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate (void) printf("%20s %-16s %s\n", "NAME", "VALUE", "DESCRIPTION"); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate for (sp = ams.ams_buf; sp < ams.ams_buf + ams.ams_len; sp++) { 5477c478bd9Sstevel@tonic-gate if (aflag == 0 && strncmp(sp->fmds_name, "fmd.", 4) == 0) 5487c478bd9Sstevel@tonic-gate continue; /* skip fmd-internal stats unless -a used */ 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate if (zflag) { 5517c478bd9Sstevel@tonic-gate switch (sp->fmds_type) { 5527c478bd9Sstevel@tonic-gate case FMD_TYPE_INT32: 5537c478bd9Sstevel@tonic-gate case FMD_TYPE_UINT32: 5547c478bd9Sstevel@tonic-gate if (sp->fmds_value.ui32 == 0) 5557c478bd9Sstevel@tonic-gate continue; 5567c478bd9Sstevel@tonic-gate break; 5577c478bd9Sstevel@tonic-gate case FMD_TYPE_INT64: 5587c478bd9Sstevel@tonic-gate case FMD_TYPE_UINT64: 5597c478bd9Sstevel@tonic-gate case FMD_TYPE_TIME: 5607c478bd9Sstevel@tonic-gate case FMD_TYPE_SIZE: 5617c478bd9Sstevel@tonic-gate if (sp->fmds_value.ui64 == 0) 5627c478bd9Sstevel@tonic-gate continue; 5637c478bd9Sstevel@tonic-gate break; 5647c478bd9Sstevel@tonic-gate case FMD_TYPE_STRING: 5657c478bd9Sstevel@tonic-gate if (sp->fmds_value.str == NULL || 5667c478bd9Sstevel@tonic-gate sp->fmds_value.str[0] == '\0') 5677c478bd9Sstevel@tonic-gate continue; 5687c478bd9Sstevel@tonic-gate break; 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate (void) printf("%20s ", sp->fmds_name); 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate switch (sp->fmds_type) { 5757c478bd9Sstevel@tonic-gate case FMD_TYPE_BOOL: 5767c478bd9Sstevel@tonic-gate (void) printf("%-16s", 5777c478bd9Sstevel@tonic-gate sp->fmds_value.bool ? "true" : "false"); 5787c478bd9Sstevel@tonic-gate break; 5797c478bd9Sstevel@tonic-gate case FMD_TYPE_INT32: 5807c478bd9Sstevel@tonic-gate (void) printf("%-16d", sp->fmds_value.i32); 5817c478bd9Sstevel@tonic-gate break; 5827c478bd9Sstevel@tonic-gate case FMD_TYPE_UINT32: 5837c478bd9Sstevel@tonic-gate (void) printf("%-16u", sp->fmds_value.ui32); 5847c478bd9Sstevel@tonic-gate break; 5857c478bd9Sstevel@tonic-gate case FMD_TYPE_INT64: 5867c478bd9Sstevel@tonic-gate (void) printf("%-16lld", sp->fmds_value.i64); 5877c478bd9Sstevel@tonic-gate break; 5887c478bd9Sstevel@tonic-gate case FMD_TYPE_UINT64: 5897c478bd9Sstevel@tonic-gate (void) printf("%-16llu", sp->fmds_value.ui64); 5907c478bd9Sstevel@tonic-gate break; 5917c478bd9Sstevel@tonic-gate case FMD_TYPE_STRING: 5927c478bd9Sstevel@tonic-gate (void) printf("%-16s", sp->fmds_value.str ? 5937c478bd9Sstevel@tonic-gate sp->fmds_value.str : "<<null>>"); 5947c478bd9Sstevel@tonic-gate break; 5957c478bd9Sstevel@tonic-gate case FMD_TYPE_TIME: 5967c478bd9Sstevel@tonic-gate (void) printf("%-16s", 5977c478bd9Sstevel@tonic-gate time2str(buf, sizeof (buf), sp->fmds_value.ui64)); 5987c478bd9Sstevel@tonic-gate break; 5997c478bd9Sstevel@tonic-gate case FMD_TYPE_SIZE: 6007c478bd9Sstevel@tonic-gate (void) printf("%-16s", 6017c478bd9Sstevel@tonic-gate size2str(buf, sizeof (buf), sp->fmds_value.ui64)); 6027c478bd9Sstevel@tonic-gate break; 6037c478bd9Sstevel@tonic-gate default: 6047c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 6057c478bd9Sstevel@tonic-gate "<<type=%u>>\n", sp->fmds_type); 6067c478bd9Sstevel@tonic-gate (void) printf("%-16s", buf); 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate (void) printf(" %s\n", sp->fmds_desc); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate (void) fmd_adm_stats_free(g_adm, &ams); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 6167c478bd9Sstevel@tonic-gate static int 6177c478bd9Sstevel@tonic-gate stat_one_serd(const fmd_adm_serdinfo_t *asi, void *ignored) 6187c478bd9Sstevel@tonic-gate { 6197c478bd9Sstevel@tonic-gate char buf1[32], buf2[32], n[32]; 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate (void) snprintf(n, sizeof (n), ">%llu", asi->asi_n); 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate (void) printf("%-36s %3s %5s %3u %24s %s\n", 6247c478bd9Sstevel@tonic-gate asi->asi_name, n, time2str(buf1, sizeof (buf1), asi->asi_t), 6257c478bd9Sstevel@tonic-gate asi->asi_count, time2str(buf2, sizeof (buf2), asi->asi_delta), 6267c478bd9Sstevel@tonic-gate (asi->asi_flags & FMD_ADM_SERD_FIRED) ? "fire" : "pend"); 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate return (0); 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate static void 6327c478bd9Sstevel@tonic-gate stat_mod_serd(const char *name) 6337c478bd9Sstevel@tonic-gate { 6347c478bd9Sstevel@tonic-gate (void) printf("%-36s %3s %5s %3s %24s %4s\n", 6357c478bd9Sstevel@tonic-gate "NAME", ">N", "T", "CNT", "DELTA", "STAT"); 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate if (fmd_adm_serd_iter(g_adm, name, stat_one_serd, NULL) != 0) 6387c478bd9Sstevel@tonic-gate die("failed to retrieve serd engines for %s", name); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate static int 6427c478bd9Sstevel@tonic-gate getint(const char *name, const char *s) 6437c478bd9Sstevel@tonic-gate { 6447c478bd9Sstevel@tonic-gate long val; 6457c478bd9Sstevel@tonic-gate char *p; 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate errno = 0; 6487c478bd9Sstevel@tonic-gate val = strtol(s, &p, 10); 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate if (errno != 0 || p == s || *p != '\0' || val < 0 || val > INT_MAX) { 6517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 6527c478bd9Sstevel@tonic-gate g_pname, name, s); 6537c478bd9Sstevel@tonic-gate exit(FMSTAT_EXIT_USAGE); 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate return ((int)val); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate static uint32_t 6607c478bd9Sstevel@tonic-gate getu32(const char *name, const char *s) 6617c478bd9Sstevel@tonic-gate { 6627c478bd9Sstevel@tonic-gate u_longlong_t val; 6637c478bd9Sstevel@tonic-gate char *p; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate errno = 0; 6667c478bd9Sstevel@tonic-gate val = strtoull(s, &p, 0); 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate if (errno != 0 || p == s || *p != '\0' || val > UINT32_MAX) { 6697c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 6707c478bd9Sstevel@tonic-gate g_pname, name, s); 6717c478bd9Sstevel@tonic-gate exit(FMSTAT_EXIT_USAGE); 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate return ((uint32_t)val); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate static int 6787c478bd9Sstevel@tonic-gate usage(FILE *fp) 6797c478bd9Sstevel@tonic-gate { 680d9638e54Smws (void) fprintf(fp, "Usage: %s [-astTz] [-m module] " 681*26fd7700SKrishnendu Sadhukhan - Sun Microsystems "[-P prog] [-d d|u] [interval [count]]\n\n", g_pname); 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate (void) fprintf(fp, 6847c478bd9Sstevel@tonic-gate "\t-a show all statistics, including those kept by fmd\n" 685*26fd7700SKrishnendu Sadhukhan - Sun Microsystems "\t-d display a timestamp in date (d) or unix time_t (u)\n" 6867c478bd9Sstevel@tonic-gate "\t-m show module-specific statistics\n" 6877c478bd9Sstevel@tonic-gate "\t-P connect to alternate fmd program\n" 6887c478bd9Sstevel@tonic-gate "\t-s show module-specific serd engines\n" 689d9638e54Smws "\t-t show transport-specific statistics\n" 690d9638e54Smws "\t-T show transport modules and authorities\n" 6917c478bd9Sstevel@tonic-gate "\t-z suppress zero-valued statistics\n"); 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate return (FMSTAT_EXIT_USAGE); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate int 6977c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 6987c478bd9Sstevel@tonic-gate { 699d9638e54Smws int opt_a = 0, opt_s = 0, opt_t = 0, opt_T = 0, opt_z = 0; 7007c478bd9Sstevel@tonic-gate const char *opt_m = NULL; 7017c478bd9Sstevel@tonic-gate int msec = 0, iter = 1; 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate uint32_t program; 7047c478bd9Sstevel@tonic-gate char *p; 7057c478bd9Sstevel@tonic-gate int c; 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate if ((p = strrchr(argv[0], '/')) == NULL) 7087c478bd9Sstevel@tonic-gate g_pname = argv[0]; 7097c478bd9Sstevel@tonic-gate else 7107c478bd9Sstevel@tonic-gate g_pname = p + 1; 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate if ((p = getenv("FMD_PROGRAM")) != NULL) 7137c478bd9Sstevel@tonic-gate program = getu32("$FMD_PROGRAM", p); 7147c478bd9Sstevel@tonic-gate else 7157c478bd9Sstevel@tonic-gate program = FMD_ADM_PROGRAM; 7167c478bd9Sstevel@tonic-gate 717*26fd7700SKrishnendu Sadhukhan - Sun Microsystems (void) setlocale(LC_ALL, ""); 718*26fd7700SKrishnendu Sadhukhan - Sun Microsystems (void) textdomain(TEXT_DOMAIN); 719*26fd7700SKrishnendu Sadhukhan - Sun Microsystems 720*26fd7700SKrishnendu Sadhukhan - Sun Microsystems while ((c = getopt(argc, argv, "ad:m:P:stTz")) != EOF) { 7217c478bd9Sstevel@tonic-gate switch (c) { 7227c478bd9Sstevel@tonic-gate case 'a': 7237c478bd9Sstevel@tonic-gate opt_a++; 7247c478bd9Sstevel@tonic-gate break; 725*26fd7700SKrishnendu Sadhukhan - Sun Microsystems case 'd': 726*26fd7700SKrishnendu Sadhukhan - Sun Microsystems if (optarg) { 727*26fd7700SKrishnendu Sadhukhan - Sun Microsystems if (*optarg == 'u') 728*26fd7700SKrishnendu Sadhukhan - Sun Microsystems timestamp_fmt = UDATE; 729*26fd7700SKrishnendu Sadhukhan - Sun Microsystems else if (*optarg == 'd') 730*26fd7700SKrishnendu Sadhukhan - Sun Microsystems timestamp_fmt = DDATE; 731*26fd7700SKrishnendu Sadhukhan - Sun Microsystems else 732*26fd7700SKrishnendu Sadhukhan - Sun Microsystems return (usage(stderr)); 733*26fd7700SKrishnendu Sadhukhan - Sun Microsystems } else { 734*26fd7700SKrishnendu Sadhukhan - Sun Microsystems return (usage(stderr)); 735*26fd7700SKrishnendu Sadhukhan - Sun Microsystems } 736*26fd7700SKrishnendu Sadhukhan - Sun Microsystems break; 7377c478bd9Sstevel@tonic-gate case 'm': 7387c478bd9Sstevel@tonic-gate opt_m = optarg; 7397c478bd9Sstevel@tonic-gate break; 7407c478bd9Sstevel@tonic-gate case 'P': 7417c478bd9Sstevel@tonic-gate program = getu32("program", optarg); 7427c478bd9Sstevel@tonic-gate break; 7437c478bd9Sstevel@tonic-gate case 's': 7447c478bd9Sstevel@tonic-gate opt_s++; 7457c478bd9Sstevel@tonic-gate break; 746d9638e54Smws case 't': 747d9638e54Smws opt_t++; 748d9638e54Smws break; 749d9638e54Smws case 'T': 750d9638e54Smws opt_T++; 751d9638e54Smws break; 7527c478bd9Sstevel@tonic-gate case 'z': 7537c478bd9Sstevel@tonic-gate opt_z++; 7547c478bd9Sstevel@tonic-gate break; 7557c478bd9Sstevel@tonic-gate default: 7567c478bd9Sstevel@tonic-gate return (usage(stderr)); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate if (optind < argc) { 7617c478bd9Sstevel@tonic-gate msec = getint("interval", argv[optind++]) * MILLISEC; 7627c478bd9Sstevel@tonic-gate iter = -1; 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate if (optind < argc) 7667c478bd9Sstevel@tonic-gate iter = getint("count", argv[optind++]); 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate if (optind < argc) 7697c478bd9Sstevel@tonic-gate return (usage(stderr)); 7707c478bd9Sstevel@tonic-gate 771d9638e54Smws if (opt_t != 0 && (opt_m != NULL || opt_s != 0)) { 772d9638e54Smws (void) fprintf(stderr, 773d9638e54Smws "%s: -t cannot be used with -m or -s\n", g_pname); 774d9638e54Smws return (FMSTAT_EXIT_USAGE); 775d9638e54Smws } 776d9638e54Smws 777d9638e54Smws if (opt_t != 0 && opt_T != 0) { 778d9638e54Smws (void) fprintf(stderr, 779d9638e54Smws "%s: -t and -T are mutually exclusive options\n", g_pname); 780d9638e54Smws return (FMSTAT_EXIT_USAGE); 781d9638e54Smws } 782d9638e54Smws 7837c478bd9Sstevel@tonic-gate if (opt_m == NULL && opt_s != 0) { 7847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7857c478bd9Sstevel@tonic-gate "%s: -s requires -m <module>\n", g_pname); 7867c478bd9Sstevel@tonic-gate return (FMSTAT_EXIT_USAGE); 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate if ((g_adm = fmd_adm_open(NULL, program, FMD_ADM_VERSION)) == NULL) 7907c478bd9Sstevel@tonic-gate die(NULL); /* fmd_adm_errmsg() has enough info */ 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate while (iter < 0 || iter-- > 0) { 793*26fd7700SKrishnendu Sadhukhan - Sun Microsystems if (timestamp_fmt != NODATE) 794*26fd7700SKrishnendu Sadhukhan - Sun Microsystems print_timestamp(timestamp_fmt); 7957c478bd9Sstevel@tonic-gate if (opt_s) 7967c478bd9Sstevel@tonic-gate stat_mod_serd(opt_m); 797d9638e54Smws else if (opt_T) 798d9638e54Smws stat_xprt_auth(opt_m); 7997c478bd9Sstevel@tonic-gate else if (opt_a || opt_m) 8007c478bd9Sstevel@tonic-gate stat_mod(opt_m, opt_a, opt_z); 801d9638e54Smws else if (opt_t) 802d9638e54Smws stat_xprt(); 8037c478bd9Sstevel@tonic-gate else 8047c478bd9Sstevel@tonic-gate stat_fmd(); 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate if (iter != 0) { 8077c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, msec); 8087c478bd9Sstevel@tonic-gate (void) putchar('\n'); 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate fmd_adm_close(g_adm); 8137c478bd9Sstevel@tonic-gate return (FMSTAT_EXIT_SUCCESS); 8147c478bd9Sstevel@tonic-gate } 815