#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 *);
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 *);
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());
}
}
void
sa_libpool_update(statistic_bag_t *sbag, int flags)
{
static int changed;
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);
}
}
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);
}
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());
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());
}