/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #include #include #include #include #include #include #include #include "stats.h" void usage(char *); void pr_err(char *, ...); static int zflag; char *prog; static void print_stats(stats_cookie_t *, cachefs_kstat_key_t *, int); int main(int argc, char **argv) { int rc = 0; int i, c, errflg = 0; stats_cookie_t *sc = NULL; cachefs_kstat_key_t *key; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif /* TEXT_DOMAIN */ (void) textdomain(TEXT_DOMAIN); if (prog = strrchr(argv[0], '/')) ++prog; else prog = argv[0]; while ((c = getopt(argc, argv, "z")) != EOF) switch (c) { case 'z': ++zflag; break; case '?': default: ++errflg; break; } if (errflg) { usage(NULL); rc = -1; goto out; } /* * handle multiple mountpoints specified on command line */ for (i = optind; i < argc; i++) { if ((sc = stats_create_mountpath(argv[i], prog)) == NULL) { pr_err(gettext("Cannot use %s"), argv[i]); rc = 1; continue; } if (stats_inerror(sc)) { pr_err(stats_errorstr(sc)); rc = stats_errno(sc); continue; } print_stats(sc, key = stats_getkey(sc), zflag); if (stats_inerror(sc)) { pr_err(stats_errorstr(sc)); rc = stats_errno(sc); } stats_destroy(sc); free(key); } /* * handle the case where no mountpoints were specified, * i.e. show stats for all. */ if (optind >= argc) { sc = stats_create_unbound(prog); while ((key = stats_next(sc)) != NULL) { if (! key->ks_mounted) { free(key); continue; } print_stats(sc, key, zflag); if (stats_inerror(sc)) { pr_err(stats_errorstr(sc)); rc = stats_errno(sc); } free(key); } stats_destroy(sc); } out: return (rc); } static void print_stats(stats_cookie_t *sc, cachefs_kstat_key_t *key, int zero) { uint_t misses, passes, fails, modifies; uint_t hitp, passtotal; uint_t gccount; u_longlong_t hits; hits = (u_longlong_t)stats_hits(sc); misses = stats_misses(sc); if (hits + misses != 0) hitp = (uint_t)((100 * hits) / (hits + misses)); else hitp = 100; passes = stats_passes(sc); fails = stats_fails(sc); passtotal = passes + fails; modifies = stats_modifies(sc); gccount = stats_gc_count(sc); printf("\n %s\n", (char *)(uintptr_t)key->ks_mountpoint); printf(gettext( "\t cache hit rate: %5u%% (%llu hits, %u misses)\n"), hitp, hits, misses); printf(gettext("\t consistency checks: %6d (%d pass, %d fail)\n"), passtotal, passes, fails); printf(gettext("\t modifies: %6d\n"), modifies); printf(gettext("\t garbage collection: %6d\n"), gccount); if (gccount != 0) { time_t gctime = stats_gc_time(sc); time_t before = stats_gc_before(sc); time_t after = stats_gc_after(sc); if (gctime != (time_t)0) printf(gettext("\tlast garbage collection: %s"), ctime(&gctime)); } if (zero) (void) stats_zero_stats(sc); } /* * * usage * * Description: * Prints a short usage message. * Arguments: * msgp message to include with the usage message * Returns: * Preconditions: */ void usage(char *msgp) { if (msgp) { pr_err("%s", msgp); } fprintf(stderr, gettext("Usage: cachefsstat [ -z ] [ path ... ]\n")); } /* * * pr_err * * Description: * Prints an error message to stderr. * Arguments: * fmt printf style format * ... arguments for fmt * Returns: * Preconditions: * precond(fmt) */ void pr_err(char *fmt, ...) { va_list ap; va_start(ap, fmt); (void) fprintf(stderr, gettext("cachefsstat: ")); (void) vfprintf(stderr, fmt, ap); (void) fprintf(stderr, "\n"); va_end(ap); }