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 /* 28 * sa_libpool - libpool statistic adapter, collect statistic data provided 29 * by libpool. 30 */ 31 32 #include <string.h> 33 #include <locale.h> 34 #include <assert.h> 35 36 #include <pool.h> 37 38 #include "utils.h" 39 #include "poolstat.h" 40 41 typedef int (*prop_walk_cb_t) 42 (pool_conf_t *, pool_elem_t *, const char *, pool_value_t *, void *); 43 44 /* user data used in the property walk callback function. */ 45 typedef struct { 46 int ud_result; 47 void* ud_bag; 48 } userdata_cb_t; 49 50 static pool_conf_t *conf; 51 static const char *conf_loc; 52 53 static void update_pset(statistic_bag_t *); 54 55 /* 56 * If not NULL use the passed 'configuration' to access the pool framework, 57 * otherwise create and open a private access point. 58 */ 59 void 60 sa_libpool_init(void *configuration) 61 { 62 if (configuration) { 63 conf = configuration; 64 } else { 65 conf_loc = pool_dynamic_location(); 66 if ((conf = pool_conf_alloc()) == NULL) 67 die(gettext(ERR_NOMEM)); 68 if (pool_conf_open(conf, conf_loc, PO_RDONLY | PO_UPDATE) 69 != PO_SUCCESS) 70 die(gettext(ERR_OPEN_STATIC), conf_loc, get_errstr()); 71 } 72 } 73 74 /*ARGSUSED*/ 75 void 76 sa_libpool_update(statistic_bag_t *sbag, int flags) 77 { 78 static int changed; 79 80 /* The SA_REFRESH flag forces the update of local data structures. */ 81 if (flags & SA_REFRESH) { 82 changed = 0; 83 if (pool_conf_update(conf, &changed) != PO_SUCCESS) 84 die(gettext(ERR_CONF_UPDATE), get_errstr()); 85 sbag->sb_changed = changed; 86 } 87 if (strcmp(sbag->sb_type, PSET_TYPE_NAME) == 0) { 88 if (changed & POU_PSET || changed & POU_CPU) 89 ((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed = 90 changed; 91 else 92 ((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed = 93 0; 94 update_pset(sbag); 95 } else if (strcmp(sbag->sb_type, POOL_TYPE_NAME) == 0) { 96 return; 97 } else { 98 die(gettext(ERR_UNSUPP_STYPE), sbag->sb_type); 99 } 100 } 101 102 /* 103 * callback function to property walker, copies the property value from 104 * the passed 'pvalue' to the corresponding field in the statistic data bag. 105 */ 106 /*ARGSUSED*/ 107 static int 108 populate_userdata_cb(pool_conf_t *unused1, pool_elem_t *unused2, 109 const char *name, pool_value_t *pval, userdata_cb_t *ud) 110 { 111 pset_statistic_bag_t *bag = (pset_statistic_bag_t *)ud->ud_bag; 112 113 ud->ud_result = 0; 114 if (strcmp("pset.min", name) == 0) { 115 ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_min); 116 } else if (strcmp("pset.max", name) == 0) { 117 ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_max); 118 } else if (strcmp("pset.load", name) == 0) { 119 uint64_t load; 120 121 ud->ud_result = pool_value_get_uint64(pval, &load); 122 bag->pset_sb_load = (double)load / 1000.0; 123 } else if (strcmp("pset.size", name) == 0) { 124 ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_size); 125 } else if (strcmp("pset.sys_id", name) == 0) { 126 ud->ud_result = pool_value_get_int64(pval, &bag->pset_sb_sysid); 127 } 128 129 return (0); 130 } 131 132 /* 133 * Update statistic data for the procssor set with the name 'sbag->name'. 134 * Use 'sbag->bag' to store the data. 135 */ 136 static void 137 update_pset(statistic_bag_t *sbag) 138 { 139 pool_resource_t *pset_reso; 140 pool_elem_t *pset_elem; 141 userdata_cb_t ud; 142 143 ud.ud_bag = (void *) sbag->bag; 144 if ((pset_reso = pool_get_resource(conf, PSET_TYPE_NAME, sbag->sb_name)) 145 == NULL) 146 die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr()); 147 if ((pset_elem = pool_resource_to_elem(conf, pset_reso)) == NULL) 148 die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr()); 149 150 /* use the property walker to collect the resource properties */ 151 if (pool_walk_properties(conf, pset_elem, &ud, 152 (prop_walk_cb_t)populate_userdata_cb) == -1) 153 die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr()); 154 } 155