xref: /illumos-gate/usr/src/cmd/pools/poolstat/sa_libpool.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * sa_libpool - libpool statistic adapter, collect statistic data provided
31  * by libpool.
32  */
33 
34 #include <string.h>
35 #include <locale.h>
36 #include <assert.h>
37 
38 #include <pool.h>
39 
40 #include "utils.h"
41 #include "poolstat.h"
42 
43 typedef int (*prop_walk_cb_t)
44 	(pool_conf_t *, pool_elem_t *, const char *, pool_value_t *, void *);
45 
46 /* user data used in the property walk callback function.	*/
47 typedef struct {
48 	int	ud_result;
49 	void*   ud_bag;
50 } userdata_cb_t;
51 
52 static pool_conf_t *conf;
53 static const char *conf_loc;
54 
55 static void update_pset(statistic_bag_t *);
56 
57 /*
58  * If not NULL use the passed 'configuration' to access the pool framework,
59  * otherwise create and open a private access point.
60  */
61 void
62 sa_libpool_init(void *configuration)
63 {
64 	if (configuration) {
65 		conf = configuration;
66 	} else {
67 		conf_loc = pool_dynamic_location();
68 		if ((conf = pool_conf_alloc()) == NULL)
69 			die(gettext(ERR_NOMEM));
70 		if (pool_conf_open(conf, conf_loc, PO_RDONLY | PO_UPDATE)
71 			!= PO_SUCCESS)
72 			die(gettext(ERR_OPEN_STATIC), conf_loc, get_errstr());
73 	}
74 }
75 
76 /*ARGSUSED*/
77 void
78 sa_libpool_update(statistic_bag_t *sbag, int flags)
79 {
80 	static int changed;
81 
82 	/* The SA_REFRESH flag forces the update of local data structures. */
83 	if (flags & SA_REFRESH) {
84 		changed = 0;
85 		if (pool_conf_update(conf, &changed) != PO_SUCCESS)
86 			die(gettext(ERR_CONF_UPDATE), get_errstr());
87 		sbag->sb_changed = changed;
88 	}
89 	if (strcmp(sbag->sb_type, PSET_TYPE_NAME) == 0) {
90 		if (changed & POU_PSET || changed & POU_CPU)
91 			((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed =
92 				changed;
93 		else
94 			((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed =
95 				0;
96 		update_pset(sbag);
97 	} else if (strcmp(sbag->sb_type, POOL_TYPE_NAME) == 0) {
98 		return;
99 	} else {
100 		die(gettext(ERR_UNSUPP_STYPE), sbag->sb_type);
101 	}
102 }
103 
104 /*
105  * callback function to property walker, copies the property value from
106  * the passed 'pvalue' to the corresponding field in the statistic data bag.
107  */
108 /*ARGSUSED*/
109 static int
110 populate_userdata_cb(pool_conf_t *unused1, pool_elem_t *unused2,
111 	const char *name, pool_value_t *pval, userdata_cb_t *ud)
112 {
113 	pset_statistic_bag_t *bag = (pset_statistic_bag_t *)ud->ud_bag;
114 
115 	ud->ud_result = 0;
116 	if (strcmp("pset.min", name) == 0) {
117 		ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_min);
118 	} else if (strcmp("pset.max", name) == 0) {
119 		ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_max);
120 	} else if (strcmp("pset.load", name) == 0) {
121 		uint64_t load;
122 
123 		ud->ud_result = pool_value_get_uint64(pval, &load);
124 		bag->pset_sb_load = (double)load / 1000.0;
125 	} else if (strcmp("pset.size", name) == 0) {
126 		ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_size);
127 	} else if (strcmp("pset.sys_id", name) == 0) {
128 		ud->ud_result = pool_value_get_int64(pval, &bag->pset_sb_sysid);
129 	}
130 
131 	return (0);
132 }
133 
134 /*
135  * Update statistic data for the procssor set with the name 'sbag->name'.
136  * Use 'sbag->bag' to store the data.
137  */
138 static void
139 update_pset(statistic_bag_t *sbag)
140 {
141 	pool_resource_t *pset_reso;
142 	pool_elem_t	*pset_elem;
143 	userdata_cb_t	ud;
144 
145 	ud.ud_bag = (void *) sbag->bag;
146 	if ((pset_reso = pool_get_resource(conf, PSET_TYPE_NAME, sbag->sb_name))
147 		== NULL)
148 		die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
149 	if ((pset_elem = pool_resource_to_elem(conf, pset_reso)) == NULL)
150 		die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
151 
152 	/* use the property walker to collect the resource properties	*/
153 	if (pool_walk_properties(conf, pset_elem, &ud,
154 		(prop_walk_cb_t)populate_userdata_cb) == -1)
155 		die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
156 }
157