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*6cb1ca52Saf  * Common Development and Distribution License (the "License").
6*6cb1ca52Saf  * 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  */
217c478bd9Sstevel@tonic-gate /*
22*6cb1ca52Saf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  * stats.c -- simple stats tracking table module
267c478bd9Sstevel@tonic-gate  *
277c478bd9Sstevel@tonic-gate  * this version of stats.c links with eft and implements the
287c478bd9Sstevel@tonic-gate  * stats using the fmd's stats API.
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/types.h>
327c478bd9Sstevel@tonic-gate #include <strings.h>
337c478bd9Sstevel@tonic-gate #include "stats.h"
347c478bd9Sstevel@tonic-gate #include "alloc.h"
357c478bd9Sstevel@tonic-gate #include "out.h"
36*6cb1ca52Saf #include "stats_impl.h"
377c478bd9Sstevel@tonic-gate #include <fm/fmd_api.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate extern fmd_hdl_t *Hdl;		/* handle from eft.c */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate static int Ext;			/* true if extended stats are enabled */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /*
447c478bd9Sstevel@tonic-gate  * stats_init -- initialize the stats module
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate void
stats_init(int ext)497c478bd9Sstevel@tonic-gate stats_init(int ext)
507c478bd9Sstevel@tonic-gate {
517c478bd9Sstevel@tonic-gate 	Ext = ext;
527c478bd9Sstevel@tonic-gate }
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate void
stats_fini(void)557c478bd9Sstevel@tonic-gate stats_fini(void)
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate }
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static struct stats *
stats_new(const char * name,const char * desc,enum stats_type t)607c478bd9Sstevel@tonic-gate stats_new(const char *name, const char *desc, enum stats_type t)
617c478bd9Sstevel@tonic-gate {
627c478bd9Sstevel@tonic-gate 	struct stats *ret = MALLOC(sizeof (*ret));
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	bzero(ret, sizeof (*ret));
657c478bd9Sstevel@tonic-gate 	ret->t = t;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	(void) strlcpy(ret->fmd_stats.fmds_desc, desc,
687c478bd9Sstevel@tonic-gate 	    sizeof (ret->fmd_stats.fmds_desc));
697c478bd9Sstevel@tonic-gate 
707aec1d6eScindi 	/* NULL name means generate a unique name */
717aec1d6eScindi 	if (name == NULL) {
727aec1d6eScindi 		static int uniqstat;
737aec1d6eScindi 
747aec1d6eScindi 		(void) snprintf(ret->fmd_stats.fmds_name,
757aec1d6eScindi 		    sizeof (ret->fmd_stats.fmds_name),
767aec1d6eScindi 		    "stat.rules%d", uniqstat++);
777aec1d6eScindi 	} else {
787aec1d6eScindi 		(void) strlcpy(ret->fmd_stats.fmds_name, name,
797aec1d6eScindi 		    sizeof (ret->fmd_stats.fmds_name));
807aec1d6eScindi 	}
817aec1d6eScindi 
827c478bd9Sstevel@tonic-gate 	switch (t) {
837c478bd9Sstevel@tonic-gate 	case STATS_COUNTER:
847c478bd9Sstevel@tonic-gate 		ret->fmd_stats.fmds_type = FMD_TYPE_INT32;
857c478bd9Sstevel@tonic-gate 		break;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	case STATS_ELAPSE:
887c478bd9Sstevel@tonic-gate 		ret->fmd_stats.fmds_type = FMD_TYPE_TIME;
897c478bd9Sstevel@tonic-gate 		break;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	case STATS_STRING:
927c478bd9Sstevel@tonic-gate 		ret->fmd_stats.fmds_type = FMD_TYPE_STRING;
937c478bd9Sstevel@tonic-gate 		break;
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	default:
967c478bd9Sstevel@tonic-gate 		out(O_DIE, "stats_new: unknown type %d", t);
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	(void) fmd_stat_create(Hdl, FMD_STAT_NOALLOC, 1, &(ret->fmd_stats));
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	return (ret);
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate void
stats_delete(struct stats * sp)1057c478bd9Sstevel@tonic-gate stats_delete(struct stats *sp)
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate 	if (sp == NULL)
1087c478bd9Sstevel@tonic-gate 		return;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	fmd_stat_destroy(Hdl, 1, &(sp->fmd_stats));
1117c478bd9Sstevel@tonic-gate 	FREE(sp);
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate struct stats *
stats_new_counter(const char * name,const char * desc,int ext)1157c478bd9Sstevel@tonic-gate stats_new_counter(const char *name, const char *desc, int ext)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate 	if (ext && !Ext)
1187c478bd9Sstevel@tonic-gate 		return (NULL);		/* extended stats not enabled */
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	return (stats_new(name, desc, STATS_COUNTER));
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate void
stats_counter_bump(struct stats * sp)1247c478bd9Sstevel@tonic-gate stats_counter_bump(struct stats *sp)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	if (sp == NULL)
1277c478bd9Sstevel@tonic-gate 		return;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	ASSERT(sp->t == STATS_COUNTER);
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	sp->fmd_stats.fmds_value.i32++;
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate void
stats_counter_add(struct stats * sp,int n)1357c478bd9Sstevel@tonic-gate stats_counter_add(struct stats *sp, int n)
1367c478bd9Sstevel@tonic-gate {
1377c478bd9Sstevel@tonic-gate 	if (sp == NULL)
1387c478bd9Sstevel@tonic-gate 		return;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	ASSERT(sp->t == STATS_COUNTER);
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	sp->fmd_stats.fmds_value.i32 += n;
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
1457aec1d6eScindi void
stats_counter_reset(struct stats * sp)1467aec1d6eScindi stats_counter_reset(struct stats *sp)
1477aec1d6eScindi {
1487aec1d6eScindi 	if (sp == NULL)
1497aec1d6eScindi 		return;
1507aec1d6eScindi 
1517aec1d6eScindi 	ASSERT(sp->t == STATS_COUNTER);
1527aec1d6eScindi 
1537aec1d6eScindi 	sp->fmd_stats.fmds_value.i32 = 0;
1547aec1d6eScindi }
1557aec1d6eScindi 
1567c478bd9Sstevel@tonic-gate int
stats_counter_value(struct stats * sp)1577c478bd9Sstevel@tonic-gate stats_counter_value(struct stats *sp)
1587c478bd9Sstevel@tonic-gate {
1597c478bd9Sstevel@tonic-gate 	if (sp == NULL)
1607c478bd9Sstevel@tonic-gate 		return (0);
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	ASSERT(sp->t == STATS_COUNTER);
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	return (sp->fmd_stats.fmds_value.i32);
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate struct stats *
stats_new_elapse(const char * name,const char * desc,int ext)1687c478bd9Sstevel@tonic-gate stats_new_elapse(const char *name, const char *desc, int ext)
1697c478bd9Sstevel@tonic-gate {
1707c478bd9Sstevel@tonic-gate 	if (ext && !Ext)
1717c478bd9Sstevel@tonic-gate 		return (NULL);		/* extended stats not enabled */
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	return (stats_new(name, desc, STATS_ELAPSE));
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate void
stats_elapse_start(struct stats * sp)1777c478bd9Sstevel@tonic-gate stats_elapse_start(struct stats *sp)
1787c478bd9Sstevel@tonic-gate {
1797c478bd9Sstevel@tonic-gate 	if (sp == NULL)
1807c478bd9Sstevel@tonic-gate 		return;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	ASSERT(sp->t == STATS_ELAPSE);
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	sp->start = gethrtime();
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate void
stats_elapse_stop(struct stats * sp)1887c478bd9Sstevel@tonic-gate stats_elapse_stop(struct stats *sp)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate 	if (sp == NULL)
1917c478bd9Sstevel@tonic-gate 		return;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 	ASSERT(sp->t == STATS_ELAPSE);
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	sp->stop = gethrtime();
1967c478bd9Sstevel@tonic-gate 	sp->fmd_stats.fmds_value.ui64 = sp->stop - sp->start;
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate struct stats *
stats_new_string(const char * name,const char * desc,int ext)2007c478bd9Sstevel@tonic-gate stats_new_string(const char *name, const char *desc, int ext)
2017c478bd9Sstevel@tonic-gate {
2027c478bd9Sstevel@tonic-gate 	struct stats *r;
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	if (ext && !Ext)
2057c478bd9Sstevel@tonic-gate 		return (NULL);		/* extended stats not enabled */
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	r = stats_new(name, desc, STATS_STRING);
2087c478bd9Sstevel@tonic-gate 	return (r);
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate void
stats_string_set(struct stats * sp,const char * s)2127c478bd9Sstevel@tonic-gate stats_string_set(struct stats *sp, const char *s)
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate 	if (sp == NULL)
2157c478bd9Sstevel@tonic-gate 		return;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	ASSERT(sp->t == STATS_STRING);
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	if (sp->fmd_stats.fmds_value.str)
2207c478bd9Sstevel@tonic-gate 		fmd_hdl_strfree(Hdl, sp->fmd_stats.fmds_value.str);
2217c478bd9Sstevel@tonic-gate 	sp->fmd_stats.fmds_value.str = fmd_hdl_strdup(Hdl, s, FMD_SLEEP);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate /*
2257c478bd9Sstevel@tonic-gate  * stats_publish -- spew all stats
2267c478bd9Sstevel@tonic-gate  *
2277c478bd9Sstevel@tonic-gate  */
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate void
stats_publish(void)2307c478bd9Sstevel@tonic-gate stats_publish(void)
2317c478bd9Sstevel@tonic-gate {
2327c478bd9Sstevel@tonic-gate 	/* nothing to do for eft */
2337c478bd9Sstevel@tonic-gate }
234