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