diff --git a/src/core/store.c b/src/core/store.c
index 764c7c7a0e7604177f18a570d68529b0aba1caed..f6c65bcf7cd2604ac78889688186ebf3d2133b18 100644 (file)
--- a/src/core/store.c
+++ b/src/core/store.c
* private variables
*/
-static sdb_avltree_t *hosts = NULL;
-static pthread_rwlock_t host_lock = PTHREAD_RWLOCK_INITIALIZER;
+typedef struct {
+ sdb_object_t super;
+
+ /* hosts are the top-level entries and
+ * reference everything else */
+ sdb_avltree_t *hosts;
+ pthread_rwlock_t host_lock;
+} sdb_store_t;
+#define ST(obj) ((sdb_store_t *)(obj))
+
+sdb_store_t *global_store = NULL;
/*
* private types
static sdb_type_t metric_type;
static sdb_type_t attribute_type;
+static int
+store_init(sdb_object_t *obj, va_list __attribute__((unused)) ap)
+{
+ int err;
+ if (! (ST(obj)->hosts = sdb_avltree_create()))
+ return -1;
+ if ((err = pthread_rwlock_init(&ST(obj)->host_lock, /* attr = */ NULL))) {
+ char errbuf[128];
+ sdb_log(SDB_LOG_ERR, "store: Failed to initialize lock: %s",
+ sdb_strerror(err, errbuf, sizeof(errbuf)));
+ return -1;
+ }
+ return 0;
+} /* store_init */
+
+static void
+store_destroy(sdb_object_t *obj)
+{
+ int err;
+ if ((err = pthread_rwlock_destroy(&ST(obj)->host_lock))) {
+ char errbuf[128];
+ sdb_log(SDB_LOG_ERR, "store: Failed to destroy lock: %s",
+ sdb_strerror(err, errbuf, sizeof(errbuf)));
+ return;
+ }
+ sdb_avltree_destroy(ST(obj)->hosts);
+ ST(obj)->hosts = NULL;
+} /* store_destroy */
+
static int
store_obj_init(sdb_object_t *obj, va_list ap)
{
sdb_data_free_datum(&ATTR(obj)->value);
} /* attr_destroy */
+static sdb_type_t store_type = {
+ /* size = */ sizeof(sdb_store_t),
+ /* init = */ store_init,
+ /* destroy = */ store_destroy,
+};
+
static sdb_type_t host_type = {
/* size = */ sizeof(sdb_host_t),
/* init = */ host_init,
*/
static sdb_host_t *
-lookup_host(const char *name, bool canonicalize)
+lookup_host(sdb_store_t *st, const char *name, bool canonicalize)
{
sdb_host_t *host;
char *cname;
assert(name);
if (! canonicalize)
- return HOST(sdb_avltree_lookup(hosts, name));
+ return HOST(sdb_avltree_lookup(st->hosts, name));
cname = strdup(name);
cname = sdb_plugin_cname(cname);
return NULL;
}
- host = HOST(sdb_avltree_lookup(hosts, cname));
+ host = HOST(sdb_avltree_lookup(st->hosts, cname));
free(cname);
return host;
} /* lookup_host */
return 0;
} /* store_metric_store */
-/* The host_lock has to be acquired before calling this function. */
+/* The store's host_lock has to be acquired before calling this function. */
static sdb_avltree_t *
get_host_children(sdb_host_t *host, int type)
{
* public API
*/
+int
+sdb_store_init(void)
+{
+ if (global_store)
+ return 0;
+
+ global_store = ST(sdb_object_create("store", store_type));
+ if (! global_store) {
+ sdb_log(SDB_LOG_ERR, "store: Failed to allocate store");
+ return -1;
+ }
+ return 0;
+} /* sdb_store_init */
+
void
sdb_store_clear(void)
{
- sdb_avltree_destroy(hosts);
- hosts = NULL;
+ if (! global_store)
+ return;
+ sdb_avltree_clear(global_store->hosts);
} /* sdb_store_clear */
int
char *cname = NULL;
int status = 0;
- if (! name)
+ if ((! global_store) || (! name))
return -1;
cname = sdb_plugin_cname(strdup(name));
return -1;
}
- pthread_rwlock_wrlock(&host_lock);
- if (! hosts)
- if (! (hosts = sdb_avltree_create()))
- status = -1;
-
- if (! status)
- status = store_obj(NULL, hosts, SDB_HOST, cname, last_update, NULL);
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_wrlock(&global_store->host_lock);
+ status = store_obj(NULL, global_store->hosts,
+ SDB_HOST, cname, last_update, NULL);
+ pthread_rwlock_unlock(&global_store->host_lock);
if (sdb_plugin_store_host(name, last_update))
status = -1;
{
sdb_host_t *host;
- if (! name)
- return NULL;
+ if ((! global_store) || (! name))
+ return false;
- host = lookup_host(name, /* canonicalize = */ 0);
+ host = lookup_host(global_store, name, /* canonicalize = */ 0);
sdb_object_deref(SDB_OBJ(host));
return host != NULL;
} /* sdb_store_has_host */
{
sdb_host_t *host;
- if (! name)
+ if ((! global_store) || (! name))
return NULL;
- host = lookup_host(name, /* canonicalize = */ 0);
+ host = lookup_host(global_store, name, /* canonicalize = */ 0);
if (! host)
return NULL;
sdb_avltree_t *attrs;
int status = 0;
- if ((! hostname) || (! key))
+ if ((! global_store) || (! hostname) || (! key))
return -1;
- pthread_rwlock_wrlock(&host_lock);
- host = lookup_host(hostname, /* canonicalize = */ 1);
+ pthread_rwlock_wrlock(&global_store->host_lock);
+ host = lookup_host(global_store, hostname, /* canonicalize = */ 1);
attrs = get_host_children(host, SDB_ATTRIBUTE);
if (! attrs) {
sdb_log(SDB_LOG_ERR, "store: Failed to store attribute '%s' - "
status = store_attr(STORE_OBJ(host), attrs, key, value, last_update);
sdb_object_deref(SDB_OBJ(host));
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
if (sdb_plugin_store_attribute(hostname, key, value, last_update))
status = -1;
int status = 0;
- if ((! hostname) || (! name))
+ if ((! global_store) || (! hostname) || (! name))
return -1;
- pthread_rwlock_wrlock(&host_lock);
- host = lookup_host(hostname, /* canonicalize = */ 1);
+ pthread_rwlock_wrlock(&global_store->host_lock);
+ host = lookup_host(global_store, hostname, /* canonicalize = */ 1);
services = get_host_children(host, SDB_SERVICE);
if (! services) {
sdb_log(SDB_LOG_ERR, "store: Failed to store service '%s' - "
name, last_update, NULL);
sdb_object_deref(SDB_OBJ(host));
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
if (status)
return status;
sdb_avltree_t *services;
int status = 0;
- if ((! hostname) || (! service) || (! key))
+ if ((! global_store) || (! hostname) || (! service) || (! key))
return -1;
- pthread_rwlock_wrlock(&host_lock);
- host = lookup_host(hostname, /* canonicalize = */ 1);
+ pthread_rwlock_wrlock(&global_store->host_lock);
+ host = lookup_host(global_store, hostname, /* canonicalize = */ 1);
services = get_host_children(host, SDB_SERVICE);
sdb_object_deref(SDB_OBJ(host));
if (! services) {
sdb_log(SDB_LOG_ERR, "store: Failed to store attribute '%s' "
"for service '%s' - host '%ss' not found",
key, service, hostname);
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return -1;
}
key, value, last_update);
sdb_object_deref(SDB_OBJ(svc));
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
if (sdb_plugin_store_service_attribute(hostname, service,
key, value, last_update))
int status = 0;
- if ((! hostname) || (! name))
+ if ((! global_store) || (! hostname) || (! name))
return -1;
if (store) {
store = NULL;
}
- pthread_rwlock_wrlock(&host_lock);
- host = lookup_host(hostname, /* canonicalize = */ 1);
+ pthread_rwlock_wrlock(&global_store->host_lock);
+ host = lookup_host(global_store, hostname, /* canonicalize = */ 1);
metrics = get_host_children(host, SDB_METRIC);
if (! metrics) {
sdb_log(SDB_LOG_ERR, "store: Failed to store metric '%s' - "
sdb_object_deref(SDB_OBJ(host));
if (status) {
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return status;
}
if (store)
if (store_metric_store(metric, store))
status = -1;
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
if (sdb_plugin_store_metric(hostname, name, store, last_update))
status = -1;
sdb_metric_t *m;
int status = 0;
- if ((! hostname) || (! metric) || (! key))
+ if ((! global_store) || (! hostname) || (! metric) || (! key))
return -1;
- pthread_rwlock_wrlock(&host_lock);
- host = lookup_host(hostname, /* canonicalize = */ 1);
+ pthread_rwlock_wrlock(&global_store->host_lock);
+ host = lookup_host(global_store, hostname, /* canonicalize = */ 1);
metrics = get_host_children(host, SDB_METRIC);
sdb_object_deref(SDB_OBJ(host));
if (! metrics) {
sdb_log(SDB_LOG_ERR, "store: Failed to store attribute '%s' "
"for metric '%s' - host '%s' not found",
key, metric, hostname);
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return -1;
}
key, value, last_update);
sdb_object_deref(SDB_OBJ(m));
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
if (sdb_plugin_store_metric_attribute(hostname, metric,
key, value, last_update))
int status = 0;
- if ((! hostname) || (! metric) || (! opts) || (! buf))
+ if ((! global_store) || (! hostname) || (! metric) || (! opts) || (! buf))
return -1;
- pthread_rwlock_rdlock(&host_lock);
- host = lookup_host(hostname, /* canonicalize = */ 1);
+ pthread_rwlock_rdlock(&global_store->host_lock);
+ host = lookup_host(global_store, hostname, /* canonicalize = */ 1);
metrics = get_host_children(host, SDB_METRIC);
sdb_object_deref(SDB_OBJ(host));
if (! metrics) {
sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
"- host '%s' not found", hostname, metric, hostname);
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return -1;
}
if (! m) {
sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
"- metric '%s' not found", hostname, metric, metric);
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return -1;
}
"- no data-store configured for the stored metric",
hostname, metric);
sdb_object_deref(SDB_OBJ(m));
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return -1;
}
strncpy(type, m->store.type, sizeof(type));
strncpy(id, m->store.id, sizeof(id));
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
ts = sdb_plugin_fetch_timeseries(type, id, opts);
if (! ts) {
sdb_avltree_iter_t *host_iter = NULL;
int status = 0;
- if (! cb)
+ if ((! global_store) || (! cb))
return -1;
if ((type != SDB_HOST) && (type != SDB_SERVICE) && (type != SDB_METRIC)) {
@@ -1008,13 +1063,10 @@ sdb_store_scan(int type, sdb_store_matcher_t *m, sdb_store_matcher_t *filter,
return -1;
}
- pthread_rwlock_rdlock(&host_lock);
-
- if (hosts) {
- host_iter = sdb_avltree_get_iter(hosts);
- if (! host_iter)
- status = -1;
- }
+ pthread_rwlock_rdlock(&global_store->host_lock);
+ host_iter = sdb_avltree_get_iter(global_store->hosts);
+ if (! host_iter)
+ status = -1;
/* has_next returns false if the iterator is NULL */
while (sdb_avltree_iter_has_next(host_iter)) {
}
sdb_avltree_iter_destroy(host_iter);
- pthread_rwlock_unlock(&host_lock);
+ pthread_rwlock_unlock(&global_store->host_lock);
return status;
} /* sdb_store_scan */