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