1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #include <stdio.h> 27*fcf3ce44SJohn Forte #include <stdlib.h> 28*fcf3ce44SJohn Forte #include <string.h> 29*fcf3ce44SJohn Forte #include <strings.h> 30*fcf3ce44SJohn Forte #include <errno.h> 31*fcf3ce44SJohn Forte #include <kstat.h> 32*fcf3ce44SJohn Forte #include <signal.h> 33*fcf3ce44SJohn Forte #include <setjmp.h> 34*fcf3ce44SJohn Forte 35*fcf3ce44SJohn Forte #include "sdbc_stats.h" 36*fcf3ce44SJohn Forte #include "report.h" 37*fcf3ce44SJohn Forte #include "common.h" 38*fcf3ce44SJohn Forte 39*fcf3ce44SJohn Forte static sigjmp_buf env; 40*fcf3ce44SJohn Forte static sig_atomic_t sig_raised = 0; 41*fcf3ce44SJohn Forte static void sig_handler(int); 42*fcf3ce44SJohn Forte 43*fcf3ce44SJohn Forte void 44*fcf3ce44SJohn Forte sig_handler(int sig) 45*fcf3ce44SJohn Forte { 46*fcf3ce44SJohn Forte switch (sig) { 47*fcf3ce44SJohn Forte case SIGSEGV: 48*fcf3ce44SJohn Forte sig_raised = 1; 49*fcf3ce44SJohn Forte siglongjmp(env, sig); 50*fcf3ce44SJohn Forte default: 51*fcf3ce44SJohn Forte exit(sig); 52*fcf3ce44SJohn Forte } 53*fcf3ce44SJohn Forte } 54*fcf3ce44SJohn Forte 55*fcf3ce44SJohn Forte /* 56*fcf3ce44SJohn Forte * kstat_retrieve() - populate the ks_data field of the kstat_t structure 57*fcf3ce44SJohn Forte * 58*fcf3ce44SJohn Forte * This function is a user-land equivalent of a ks_snapshot 59*fcf3ce44SJohn Forte * 60*fcf3ce44SJohn Forte * parameters 61*fcf3ce44SJohn Forte * kstat_ctl_t *kc - kstat_ctl_t structure representing returned from 62*fcf3ce44SJohn Forte * kstat_open() 63*fcf3ce44SJohn Forte * kstat_t *ksp - kstat_t strcture to popluate ks_data into 64*fcf3ce44SJohn Forte * 65*fcf3ce44SJohn Forte * returns 66*fcf3ce44SJohn Forte * NULL pointer on failure 67*fcf3ce44SJohn Forte * kstat_t * structure on success 68*fcf3ce44SJohn Forte */ 69*fcf3ce44SJohn Forte kstat_t * 70*fcf3ce44SJohn Forte kstat_retrieve(kstat_ctl_t *kc, kstat_t *ksp) 71*fcf3ce44SJohn Forte { 72*fcf3ce44SJohn Forte 73*fcf3ce44SJohn Forte kstat_t *rval; 74*fcf3ce44SJohn Forte kstat_named_t *knp; 75*fcf3ce44SJohn Forte char *end; 76*fcf3ce44SJohn Forte int i; 77*fcf3ce44SJohn Forte struct sigaction segv_act; /* default actions */ 78*fcf3ce44SJohn Forte 79*fcf3ce44SJohn Forte if (ksp == NULL) 80*fcf3ce44SJohn Forte return (NULL); 81*fcf3ce44SJohn Forte 82*fcf3ce44SJohn Forte if (ksp->ks_data == NULL && 83*fcf3ce44SJohn Forte kstat_read(kc, ksp, NULL) == -1) 84*fcf3ce44SJohn Forte return (NULL); 85*fcf3ce44SJohn Forte 86*fcf3ce44SJohn Forte rval = (kstat_t *)calloc(1, sizeof (*ksp)); 87*fcf3ce44SJohn Forte memcpy(rval, ksp, sizeof (*ksp)); 88*fcf3ce44SJohn Forte 89*fcf3ce44SJohn Forte rval->ks_data = (void *) calloc(1, ksp->ks_data_size); 90*fcf3ce44SJohn Forte memcpy(rval->ks_data, ksp->ks_data, 91*fcf3ce44SJohn Forte sizeof (kstat_named_t) * ksp->ks_ndata); 92*fcf3ce44SJohn Forte 93*fcf3ce44SJohn Forte /* special handling for variable length string KSTAT_DATA_STRING */ 94*fcf3ce44SJohn Forte knp = (kstat_named_t *)rval->ks_data; 95*fcf3ce44SJohn Forte end = (char *)(knp + ksp->ks_ndata); 96*fcf3ce44SJohn Forte for (i = 0; i < ksp->ks_ndata; i++, knp++) { 97*fcf3ce44SJohn Forte if (knp->data_type == KSTAT_DATA_STRING && 98*fcf3ce44SJohn Forte KSTAT_NAMED_STR_PTR(knp) != NULL) { 99*fcf3ce44SJohn Forte /* catch SIGSEGV (bug 6384130) */ 100*fcf3ce44SJohn Forte sig_raised = 0; 101*fcf3ce44SJohn Forte (void) sigaction(SIGSEGV, NULL, &segv_act); 102*fcf3ce44SJohn Forte (void) signal(SIGSEGV, sig_handler); 103*fcf3ce44SJohn Forte 104*fcf3ce44SJohn Forte strncpy(end, KSTAT_NAMED_STR_PTR(knp), 105*fcf3ce44SJohn Forte KSTAT_NAMED_STR_BUFLEN(knp)); 106*fcf3ce44SJohn Forte KSTAT_NAMED_STR_PTR(knp) = end; 107*fcf3ce44SJohn Forte end += KSTAT_NAMED_STR_BUFLEN(knp); 108*fcf3ce44SJohn Forte 109*fcf3ce44SJohn Forte /* bug 6384130 */ 110*fcf3ce44SJohn Forte (void) sigsetjmp(env, 0); 111*fcf3ce44SJohn Forte if (sig_raised) { 112*fcf3ce44SJohn Forte bzero(end, KSTAT_NAMED_STR_BUFLEN(knp)); 113*fcf3ce44SJohn Forte KSTAT_NAMED_STR_PTR(knp) = end; 114*fcf3ce44SJohn Forte end += KSTAT_NAMED_STR_BUFLEN(knp); 115*fcf3ce44SJohn Forte } 116*fcf3ce44SJohn Forte (void) sigaction(SIGSEGV, &segv_act, NULL); 117*fcf3ce44SJohn Forte } 118*fcf3ce44SJohn Forte } 119*fcf3ce44SJohn Forte 120*fcf3ce44SJohn Forte return (rval); 121*fcf3ce44SJohn Forte } 122*fcf3ce44SJohn Forte 123*fcf3ce44SJohn Forte /* 124*fcf3ce44SJohn Forte * kstat_value() - retrieve value of a field in a kstat_named_t kstat. 125*fcf3ce44SJohn Forte * 126*fcf3ce44SJohn Forte * parameters 127*fcf3ce44SJohn Forte * kstat_t *ksp - kstat containing the field 128*fcf3ce44SJohn Forte * char *name - text string representing the field name 129*fcf3ce44SJohn Forte * 130*fcf3ce44SJohn Forte * returns 131*fcf3ce44SJohn Forte * void * - pointer to data retrieved 132*fcf3ce44SJohn Forte */ 133*fcf3ce44SJohn Forte void * 134*fcf3ce44SJohn Forte kstat_value(kstat_t *ksp, char *name) 135*fcf3ce44SJohn Forte { 136*fcf3ce44SJohn Forte kstat_named_t *knm; 137*fcf3ce44SJohn Forte 138*fcf3ce44SJohn Forte if ((knm = kstat_data_lookup(ksp, name)) == NULL) 139*fcf3ce44SJohn Forte return (NULL); 140*fcf3ce44SJohn Forte 141*fcf3ce44SJohn Forte switch (knm->data_type) { 142*fcf3ce44SJohn Forte case KSTAT_DATA_CHAR : 143*fcf3ce44SJohn Forte return (knm->value.c); 144*fcf3ce44SJohn Forte case KSTAT_DATA_INT32 : 145*fcf3ce44SJohn Forte return (&knm->value.i32); 146*fcf3ce44SJohn Forte case KSTAT_DATA_UINT32 : 147*fcf3ce44SJohn Forte return (&knm->value.ui32); 148*fcf3ce44SJohn Forte case KSTAT_DATA_INT64 : 149*fcf3ce44SJohn Forte return (&knm->value.i64); 150*fcf3ce44SJohn Forte case KSTAT_DATA_UINT64 : 151*fcf3ce44SJohn Forte return (&knm->value.ui64); 152*fcf3ce44SJohn Forte case KSTAT_DATA_STRING : 153*fcf3ce44SJohn Forte return (KSTAT_NAMED_STR_PTR(knm)); 154*fcf3ce44SJohn Forte } 155*fcf3ce44SJohn Forte 156*fcf3ce44SJohn Forte return (NULL); 157*fcf3ce44SJohn Forte } 158*fcf3ce44SJohn Forte 159*fcf3ce44SJohn Forte /* 160*fcf3ce44SJohn Forte * kstat_free() - deallocated memory associated with a kstat 161*fcf3ce44SJohn Forte * 162*fcf3ce44SJohn Forte * paramters 163*fcf3ce44SJohn Forte * kstat_t ksp - kstat to be deallocated 164*fcf3ce44SJohn Forte * 165*fcf3ce44SJohn Forte * returns 166*fcf3ce44SJohn Forte * void 167*fcf3ce44SJohn Forte */ 168*fcf3ce44SJohn Forte void 169*fcf3ce44SJohn Forte kstat_free(kstat_t *ksp) 170*fcf3ce44SJohn Forte { 171*fcf3ce44SJohn Forte if (ksp != NULL) { 172*fcf3ce44SJohn Forte if (ksp->ks_data != NULL) 173*fcf3ce44SJohn Forte free(ksp->ks_data); 174*fcf3ce44SJohn Forte free(ksp); 175*fcf3ce44SJohn Forte } 176*fcf3ce44SJohn Forte } 177*fcf3ce44SJohn Forte 178*fcf3ce44SJohn Forte uint32_t 179*fcf3ce44SJohn Forte kstat_delta(kstat_t *pksp, kstat_t *cksp, char *name) 180*fcf3ce44SJohn Forte { 181*fcf3ce44SJohn Forte uint32_t *pv, *cv; 182*fcf3ce44SJohn Forte 183*fcf3ce44SJohn Forte pv = kstat_value(pksp, name); 184*fcf3ce44SJohn Forte cv = kstat_value(cksp, name); 185*fcf3ce44SJohn Forte 186*fcf3ce44SJohn Forte return (u32_delta(*pv, *cv)); 187*fcf3ce44SJohn Forte } 188