summaryrefslogtreecommitdiff
path: root/usr/src/cmd/avs/dsstat/sdbc_stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/avs/dsstat/sdbc_stats.c')
-rw-r--r--usr/src/cmd/avs/dsstat/sdbc_stats.c788
1 files changed, 0 insertions, 788 deletions
diff --git a/usr/src/cmd/avs/dsstat/sdbc_stats.c b/usr/src/cmd/avs/dsstat/sdbc_stats.c
deleted file mode 100644
index f1af1acdd0..0000000000
--- a/usr/src/cmd/avs/dsstat/sdbc_stats.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (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 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include <kstat.h>
-
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/sd_bcache.h>
-
-#include "sdbc_stats.h"
-
-#include "dsstat.h"
-#include "common.h"
-#include "report.h"
-
-static sdbcstat_t *sdbc_top;
-kstat_t *sdbc_global = NULL;
-
-void sdbc_header();
-int sdbc_value_check(sdbcstat_t *);
-int sdbc_validate(kstat_t *);
-uint32_t sdbc_getdelta(sdbcstat_t *, char *);
-
-void sdbc_addstat(sdbcstat_t *);
-sdbcstat_t *sdbc_delstat(sdbcstat_t *);
-void center(int, char *);
-
-/*
- * sdbc_discover() - looks for new statistics to be monitored.
- * Verifies that any statistics found are now already being
- * monitored.
- *
- */
-int
-sdbc_discover(kstat_ctl_t *kc)
-{
- static int validated = 0;
-
- kstat_t *ksp;
-
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- int kinst;
- char kname[KSTAT_STRLEN + 1];
- sdbcstat_t *cur;
- sdbcstat_t *sdbcstat = NULL;
- kstat_t *io_ksp;
-
- if (strcmp(ksp->ks_module, SDBC_KSTAT_MODULE) != 0 ||
- strncmp(ksp->ks_name, SDBC_KSTAT_CDSTATS, 2) != 0)
- continue;
-
- if (kstat_read(kc, ksp, NULL) == -1)
- continue;
-
- /*
- * Validate kstat structure
- */
- if (! validated) {
- if (sdbc_validate(ksp))
- return (EINVAL);
-
- validated++;
- }
-
- /*
- * Duplicate check
- */
- for (cur = sdbc_top; cur; cur = cur->next) {
- char *cur_vname, *tst_vname;
-
- cur_vname = kstat_value(cur->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
-
- tst_vname = kstat_value(ksp,
- SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(cur_vname, tst_vname, NAMED_LEN) == 0)
- goto next;
- }
-
- /*
- * Initialize new record
- */
- sdbcstat = (sdbcstat_t *)calloc(1, sizeof (sdbcstat_t));
-
- kinst = ksp->ks_instance;
-
- /*
- * Set kstat
- */
- sdbcstat->pre_set = kstat_retrieve(kc, ksp);
-
- if (sdbcstat->pre_set == NULL)
- goto next;
-
- sdbcstat->collected |= GOT_SET_KSTAT;
-
- /*
- * I/O kstat
- */
- (void) sprintf(kname, "%s%d", SDBC_IOKSTAT_CDSTATS, kinst);
-
- io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
- sdbcstat->pre_io = kstat_retrieve(kc, io_ksp);
-
- if (sdbcstat->pre_io == NULL)
- goto next;
-
- sdbcstat->collected |= GOT_IO_KSTAT;
-
-next:
- /*
- * Check if we got a complete set of stats
- */
- if (sdbcstat == NULL)
- continue;
-
- if (SDBC_COMPLETE(sdbcstat->collected)) {
- (void) sdbc_delstat(sdbcstat);
- continue;
- }
-
- sdbc_addstat(sdbcstat);
- }
-
- if (sdbc_top == NULL)
- return (EAGAIN);
-
- return (0);
-}
-
-/*
- * sdbc_update() - updates all of the statistics currently being monitored.
- *
- */
-int
-sdbc_update(kstat_ctl_t *kc)
-{
- kstat_t *ksp;
- sdbcstat_t *cur;
-
- /* Update global kstat information */
- ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, -1, SDBC_KSTAT_GSTATS);
-
- if (ksp == NULL)
- return (EAGAIN);
-
- if (sdbc_global)
- kstat_free(sdbc_global);
-
- sdbc_global = kstat_retrieve(kc, ksp);
-
- for (cur = sdbc_top; cur != NULL; cur = cur->next) {
- int kinst;
- char *kname, *cname, *pname;
-
- kstat_t *set_ksp, *io_ksp;
-
- cur->collected = 0;
-
- /*
- * Age off old stats
- */
- if (cur->cur_set != NULL) {
- kstat_free(cur->pre_set);
- kstat_free(cur->pre_io);
-
- cur->pre_set = cur->cur_set;
- cur->pre_io = cur->cur_io;
- }
-
- /*
- * Update set kstat
- */
- kinst = cur->pre_set->ks_instance;
- kname = cur->pre_set->ks_name;
-
- set_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
-
- if ((cur->cur_set = kstat_retrieve(kc, set_ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_SET_KSTAT;
-
- /*
- * Validate set
- */
- pname = kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME);
- cname = kstat_value(cur->cur_set, SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(pname, cname, NAMED_LEN) != 0)
- continue;
-
- /*
- * Update I/O kstat
- */
- kinst = cur->pre_io->ks_instance;
- kname = cur->pre_io->ks_name;
-
- io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
-
- if ((cur->cur_io = kstat_retrieve(kc, io_ksp)) == NULL)
- continue;
-
- cur->collected |= GOT_IO_KSTAT;
- }
-
- return (0);
-}
-
-/*
- * sdbc_report() - outputs statistics for the statistics currently being
- * monitored. Deletes statistics for volumes that have been disabled.
- *
- */
-int
-sdbc_report()
-{
- vslist_t *vslist = vs_top;
- sdbcstat_t *cur, *pre = NULL;
-
- if (sdbc_top == NULL)
- return (0);
-
- for (cur = sdbc_top; cur != NULL; ) { /* CSTYLED */
- static uint32_t linesout = 0;
- uint32_t *offline;
-
- char volname[NAMED_LEN + 1];
- char rmode[STAT_HDR_SIZE];
- char wmode[STAT_HDR_SIZE];
-
- /* Parse volume name */
- (void) strncpy(volname, kstat_value(cur->pre_set,
- SDBC_CDKSTAT_VOL_NAME), NAMED_LEN);
- volname[NAMED_LEN] = '\0';
-
- /* Check to see if the user specified this volume */
- for (vslist = vs_top; vslist != NULL; vslist = vslist->next)
- if (strcmp(volname, vslist->volname) == 0)
- break;
-
- if (vs_top != NULL && vslist == NULL)
- goto next;
-
- /* Check if volume is offline and zflag applies */
- if (zflag && sdbc_value_check(cur) == 0)
- goto next;
-
- /* Output volume name */
- sdbc_header();
-
- (void) printf(DATA_C16, volname);
-
- if (SDBC_COMPLETE(cur->collected)) {
- sdbcstat_t *next = sdbc_delstat(cur);
-
- if (! pre)
- cur = sdbc_top = next;
- else
- cur = pre->next = next;
-
- (void) printf(" <<volume disabled>>\n");
- continue;
- }
-
- offline = kstat_value(cur->cur_set, SDBC_CDKSTAT_FAILED);
- if (*offline) {
- (void) printf(" <<volume offline>>\n");
- linesout++;
- goto next;
- }
-
- /* Type/status flags */
- if (dflags & FLAGS) {
-
- uint32_t *dhint, *nhint;
- uint32_t hints;
-
- dhint = kstat_value(cur->cur_set, SDBC_CDKSTAT_CDHINTS);
- nhint = kstat_value(sdbc_global, SDBC_GKSTAT_NODEHINTS);
-
- if (! nhint)
- return (EINVAL);
-
- hints = *nhint;
- hints &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU |
- NSC_NOCACHE);
- hints |= *dhint;
-
- if (hints & NSC_NOCACHE)
- (void) strcpy(rmode, "D");
- else
- (void) strcpy(rmode, "C");
-
- if ((hints & NSC_FORCED_WRTHRU) || (hints & NSC_WRTHRU))
- (void) strcpy(wmode, "D");
- else
- (void) strcpy(wmode, "C");
-
- (void) printf(DATA_C2, rmode);
- (void) printf(DATA_C2, wmode);
- }
-
- /* Output set information */
- cd_report(cur);
-
-next:
- pre = cur;
- cur = cur->next;
- }
-
- return (0);
-}
-
-/*
- * sdbc_header() - outputs an appropriate header by referencing the
- * global variables dflsgs
- *
- */
-void
-sdbc_header()
-{
- int rcount = 0;
-
- if (hflags == HEADERS_EXL)
- if ((linesout % DISPLAY_LINES) != 0)
- return;
-
- if (hflags == HEADERS_BOR)
- if (linesout != 0)
- return;
-
- if (hflags & HEADERS_ATT)
- if (hflags & HEADERS_OUT)
- return;
- else
- hflags |= HEADERS_OUT;
-
- if (linesout)
- (void) printf("\n");
-
- /* first line header */
- if (! (dflags & SUMMARY) && dflags != FLAGS) {
-
- (void) printf(VOL_HDR_FMT, " ");
-
- if (dflags & FLAGS) {
- (void) printf(STAT_HDR_FMT, " ");
- (void) printf(STAT_HDR_FMT, " ");
- }
-
- if (dflags & READ) {
- int size;
-
- size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE;
- center(size, "- read -");
- rcount++;
- }
-
- if (dflags & WRITE) {
- int size;
-
- size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE;
- center(size, "- write -");
- rcount++;
- }
-
- if (dflags != FLAGS)
- (void) printf("\n");
- }
-
- /* second line header */
- (void) printf(VOL_HDR_FMT, "volume");
-
- if (dflags & FLAGS) {
- (void) printf(STAT_HDR_FMT, "rd");
- (void) printf(STAT_HDR_FMT, "wr");
- }
-
- if (dflags & SUMMARY) {
- (void) printf(KPS_HDR_FMT, "ckps");
- (void) printf(KPS_HDR_FMT, "dkps");
- (void) printf(HIT_HDR_FMT, HIT_HDR_TXT);
-
- goto out;
- }
-
- if (dflags & READ) {
- (void) printf(KPS_HDR_FMT, "ckps");
- (void) printf(KPS_HDR_FMT, "dkps");
- (void) printf(HIT_HDR_FMT, RHIT_HDR_TXT);
- }
-
- if (dflags & WRITE) {
- (void) printf(KPS_HDR_FMT, "ckps");
- (void) printf(KPS_HDR_FMT, "dkps");
- (void) printf(HIT_HDR_FMT, WHIT_HDR_TXT);
- }
-
- if (dflags & DESTAGED)
- (void) printf(KPS_HDR_FMT, "dstg");
-
- if (dflags & WRCANCEL)
- (void) printf(KPS_HDR_FMT, "cwrl");
-
-out:
- (void) printf("\n");
-}
-
-/*
- * sdbc_getstat() - find cache stat by name matching
- *
- * paraemters
- * char *vn - the volume name to match against
- * returns
- * sdbcstat_t * - the matching strcture, NULL if not found
- */
-sdbcstat_t *
-sdbc_getstat(char *vn)
-{
- sdbcstat_t *cur, *pre = NULL;
-
- for (cur = sdbc_top; cur; ) { /* CSTYLED */
- char *volname =
- kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME);
-
- if (SDBC_COMPLETE(cur->collected)) {
- sdbcstat_t *next = sdbc_delstat(cur);
-
- if (! pre)
- cur = sdbc_top = next;
- else
- cur = pre->next = next;
-
- continue;
- }
-
- if (strncmp(volname, vn, NAMED_LEN) == 0)
- return (cur);
-
- pre = cur;
- cur = cur->next;
- }
-
- return (NULL);
-}
-
-/*
- * sdbc_addstat() - adds a fully populated sdbcstat_t structure
- * to the linked list of currently monitored kstats. The structure
- * will be added in alphabetical order, using the volume name as the
- * key.
- *
- * parameters
- * sdbcstat_t *sdbcstat - to be added to the list.
- *
- */
-void
-sdbc_addstat(sdbcstat_t *sdbcstat)
-{
- sdbcstat_t *cur;
-
- if (sdbc_top == NULL) {
- sdbc_top = sdbcstat;
- return;
- }
-
- for (cur = sdbc_top; cur != NULL; cur = cur->next) {
- char *cur_vname, *nxt_vname, *tst_vname;
-
- cur_vname = kstat_value(cur->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
- tst_vname = kstat_value(sdbcstat->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(cur_vname, tst_vname, NAMED_LEN) > 0) {
- if (cur == sdbc_top)
- sdbc_top = sdbcstat;
-
- sdbcstat->next = cur;
-
- return;
- }
-
- /*
- * If we get to the last item in the list, then just
- * add this one to the end
- */
- if (cur->next == NULL) {
- cur->next = sdbcstat;
- return;
- }
-
- nxt_vname = kstat_value(cur->next->pre_set,
- SDBC_CDKSTAT_VOL_NAME);
-
- if (strncmp(nxt_vname, tst_vname, NAMED_LEN) > 0) {
- sdbcstat->next = cur->next;
- cur->next = sdbcstat;
- return;
- }
- }
-}
-
-/*
- * sdbc_delstat() - deallocate memory for the structure being
- * passed in.
- *
- * parameters
- * sdbcstat_t *sdbcstat - structure to be deallocated
- *
- * returns
- * sdbcstat_t * - pointer to the "next" structures in the
- * linked list. May be NULL if we are removing the last
- * structure in the linked list.
- */
-sdbcstat_t *
-sdbc_delstat(sdbcstat_t *sdbcstat)
-{
-
- sdbcstat_t *next = sdbcstat->next;
-
- kstat_free(sdbcstat->pre_set);
- kstat_free(sdbcstat->pre_io);
- kstat_free(sdbcstat->cur_set);
- kstat_free(sdbcstat->cur_io);
-
- free(sdbcstat);
- sdbcstat = NULL;
-
- return (next);
-}
-
-/*
- * sdbc_value_check() - Checks for activity, supports -z switch
- *
- * parameters
- * sdbcstat_t *sdbcstat - structure to be checked
- *
- * returns
- * 1 - activity
- * 0 - no activity
- */
-int
-sdbc_value_check(sdbcstat_t *sdbcstat)
-{
- if (SDBC_COMPLETE(sdbcstat->collected))
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE) != 0)
- return (1);
-
- if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS) != 0)
- return (1);
-
- if (io_value_check(sdbcstat->pre_io->ks_data,
- sdbcstat->cur_io->ks_data) != 0)
- return (1);
-
- return (0);
-}
-
-/*
- * sdbc_validate() - validates the structure of the kstats by attempting to
- * lookup fields used by this module
- *
- * parameters
- * kstat_t *ksp - kstat to be examined
- *
- * returns
- * 1 - one or more fields missing
- * 0 - all fields present
- */
-int
-sdbc_validate(kstat_t *ksp)
-{
- if (! kstat_value(ksp, SDBC_CDKSTAT_VOL_NAME) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_FAILED) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_CDHINTS) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_READ) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_DISK_READ) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_WRITE) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_DISK_WRITE) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_DESTAGED) ||
- ! kstat_value(ksp, SDBC_CDKSTAT_WRCANCELNS))
- return (1);
-
- return (0);
-}
-
-/*
- * sdbc_getvalues() - populates a values structure with data obtained from the
- * kstat
- *
- * parameters
- * sdbcstat_t *sdbcstat - pointer to the structure containing the kstats
- * sdbcvals_t *vals - pointer to the structure that will receive the values
- * int flags - flags that describe adjustments made to the values
- *
- * returns
- * 1 - failure
- * 0 - success
- */
-int
-sdbc_getvalues(sdbcstat_t *sdbcstat, sdbcvals_t *vals, int flags)
-{
- int divisor = 0;
- int factors;
- uint64_t hr_etime;
- double etime;
-
- kstat_io_t *cur;
- kstat_io_t *pre;
-
- if (sdbcstat == NULL)
- return (1);
-
- cur = sdbcstat->cur_io->ks_data;
- pre = sdbcstat->pre_io->ks_data;
-
- hr_etime = hrtime_delta(pre->rlastupdate, cur->rlastupdate);
- etime = hr_etime / (double)NANOSEC;
-
- /* read data */
- vals->cache_read =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ));
- vals->disk_read =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ));
-
-
- vals->total_reads = vals->cache_read + vals->disk_read;
-
- if (vals->cache_read == 0)
- vals->read_hit = 0.0;
- else
- vals->read_hit =
- ((float)vals->cache_read / vals->total_reads) * 100.0;
-
- /* write data */
- vals->cache_write =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE));
- vals->disk_write =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE));
-
- vals->total_writes = vals->cache_write + vals->disk_write;
-
- vals->destaged =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DESTAGED));
-
- if (vals->cache_write == 0)
- vals->write_hit = 0.0;
- else
- vals->write_hit = ((float)vals->cache_write /
- (vals->total_writes - vals->destaged)) * 100.0;
-
- /* miscellaneous */
- vals->write_cancellations =
- FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS));
-
- vals->total_cache = vals->cache_read + vals->cache_write;
- vals->total_disk = vals->disk_read + vals->disk_write;
-
- /* total cache hit calculation */
- vals->cache_hit = 0;
- factors = 0;
-
- if (vals->cache_read != 0) {
- vals->cache_hit += vals->read_hit;
- factors++;
- }
-
- if (vals->cache_write != 0) {
- vals->cache_hit += vals->write_hit;
- factors++;
- }
-
- if (vals->cache_hit)
- vals->cache_hit /= (float)factors;
-
- /* adjustments */
- divisor = 1;
-
- if (flags & SDBC_KBYTES)
- divisor *= KILOBYTE;
- if ((flags & SDBC_INTAVG) && (etime > 0))
- divisor *= etime;
-
- if (divisor != 1) {
- vals->cache_read /= divisor;
- vals->disk_read /= divisor;
- vals->total_reads /= divisor;
-
- vals->cache_write /= divisor;
- vals->disk_write /= divisor;
- vals->total_writes /= divisor;
-
- vals->total_cache /= divisor;
- vals->total_disk /= divisor;
-
- vals->destaged /= divisor;
- vals->write_cancellations /= divisor;
- }
-
- return (0);
-}
-
-/*
- * sdbc_getdelta() - calculates the difference between two kstat fields
- *
- * parameters
- * sdbcstat_t *sdbcstat - the SDBC stat strcture containing the two fields
- * char *name - the name of the fields
- * returns
- * uint32_t value of the differences adjusted for overflow of the data type
- */
-uint32_t
-sdbc_getdelta(sdbcstat_t *sdbcstat, char *name)
-{
- uint32_t *cur_val;
- uint32_t *pre_val;
-
- pre_val = kstat_value(sdbcstat->pre_set, name);
- cur_val = kstat_value(sdbcstat->cur_set, name);
-
- return (u32_delta(*pre_val, *cur_val));
-}
-
-void
-center(int size, char *hdr)
-{
- int lpad = 0;
- int rpad = 0;
- char fmt[10];
-
- if (size == 0)
- return;
-
- if (strlen(hdr) < size) {
- lpad = (size - strlen(hdr)) / 2;
-
- if (lpad * 2 < size)
- lpad++;
-
- rpad = size - (lpad + strlen(hdr));
- }
-
-output:
- (void) sprintf(fmt, "%%%ds%%s%%%ds", lpad, rpad);
- (void) printf(fmt, " ", hdr, " ");
-}