OpenSolaris_b135/cmd/pools/poolstat/sa_libpool.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*
 * sa_libpool - libpool statistic adapter, collect statistic data provided
 * by libpool.
 */

#include <string.h>
#include <locale.h>
#include <assert.h>

#include <pool.h>

#include "utils.h"
#include "poolstat.h"

typedef int (*prop_walk_cb_t)
	(pool_conf_t *, pool_elem_t *, const char *, pool_value_t *, void *);

/* user data used in the property walk callback function.	*/
typedef struct {
	int	ud_result;
	void*   ud_bag;
} userdata_cb_t;

static pool_conf_t *conf;
static const char *conf_loc;

static void update_pset(statistic_bag_t *);

/*
 * If not NULL use the passed 'configuration' to access the pool framework,
 * otherwise create and open a private access point.
 */
void
sa_libpool_init(void *configuration)
{
	if (configuration) {
		conf = configuration;
	} else {
		conf_loc = pool_dynamic_location();
		if ((conf = pool_conf_alloc()) == NULL)
			die(gettext(ERR_NOMEM));
		if (pool_conf_open(conf, conf_loc, PO_RDONLY | PO_UPDATE)
			!= PO_SUCCESS)
			die(gettext(ERR_OPEN_STATIC), conf_loc, get_errstr());
	}
}

/*ARGSUSED*/
void
sa_libpool_update(statistic_bag_t *sbag, int flags)
{
	static int changed;

	/* The SA_REFRESH flag forces the update of local data structures. */
	if (flags & SA_REFRESH) {
		changed = 0;
		if (pool_conf_update(conf, &changed) != PO_SUCCESS)
			die(gettext(ERR_CONF_UPDATE), get_errstr());
		sbag->sb_changed = changed;
	}
	if (strcmp(sbag->sb_type, PSET_TYPE_NAME) == 0) {
		if (changed & POU_PSET || changed & POU_CPU)
			((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed =
				changed;
		else
			((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed =
				0;
		update_pset(sbag);
	} else if (strcmp(sbag->sb_type, POOL_TYPE_NAME) == 0) {
		return;
	} else {
		die(gettext(ERR_UNSUPP_STYPE), sbag->sb_type);
	}
}

/*
 * callback function to property walker, copies the property value from
 * the passed 'pvalue' to the corresponding field in the statistic data bag.
 */
/*ARGSUSED*/
static int
populate_userdata_cb(pool_conf_t *unused1, pool_elem_t *unused2,
	const char *name, pool_value_t *pval, userdata_cb_t *ud)
{
	pset_statistic_bag_t *bag = (pset_statistic_bag_t *)ud->ud_bag;

	ud->ud_result = 0;
	if (strcmp("pset.min", name) == 0) {
		ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_min);
	} else if (strcmp("pset.max", name) == 0) {
		ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_max);
	} else if (strcmp("pset.load", name) == 0) {
		uint64_t load;

		ud->ud_result = pool_value_get_uint64(pval, &load);
		bag->pset_sb_load = (double)load / 1000.0;
	} else if (strcmp("pset.size", name) == 0) {
		ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_size);
	} else if (strcmp("pset.sys_id", name) == 0) {
		ud->ud_result = pool_value_get_int64(pval, &bag->pset_sb_sysid);
	}

	return (0);
}

/*
 * Update statistic data for the procssor set with the name 'sbag->name'.
 * Use 'sbag->bag' to store the data.
 */
static void
update_pset(statistic_bag_t *sbag)
{
	pool_resource_t *pset_reso;
	pool_elem_t	*pset_elem;
	userdata_cb_t	ud;

	ud.ud_bag = (void *) sbag->bag;
	if ((pset_reso = pool_get_resource(conf, PSET_TYPE_NAME, sbag->sb_name))
		== NULL)
		die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
	if ((pset_elem = pool_resource_to_elem(conf, pset_reso)) == NULL)
		die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());

	/* use the property walker to collect the resource properties	*/
	if (pool_walk_properties(conf, pset_elem, &ud,
		(prop_walk_cb_t)populate_userdata_cb) == -1)
		die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
}