Code

store: Fixed a memory leak in fetch_timeseries().
[sysdb.git] / src / core / store.c
index ad59a2e99df3612178445edafe02eeabe3d9fa69..a1cf8f6bc44b6ba816fc66ee729189c4371da07d 100644 (file)
@@ -256,7 +256,7 @@ static sdb_type_t sdb_attribute_type = {
  */
 
 static sdb_host_t *
-lookup_host(const char *name, _Bool canonicalize)
+lookup_host(const char *name, bool canonicalize)
 {
        sdb_host_t *host;
        char *cname;
@@ -536,11 +536,14 @@ sdb_store_host(const char *name, sdb_time_t last_update)
                status = store_obj(NULL, hosts, SDB_HOST, cname, last_update, NULL);
        pthread_rwlock_unlock(&host_lock);
 
+       if (sdb_plugin_store_host(name, last_update))
+               status = -1;
+
        free(cname);
        return status;
 } /* sdb_store_host */
 
-_Bool
+bool
 sdb_store_has_host(const char *name)
 {
        sdb_host_t *host;
@@ -594,6 +597,9 @@ sdb_store_attribute(const char *hostname,
 
        sdb_object_deref(SDB_OBJ(host));
        pthread_rwlock_unlock(&host_lock);
+
+       if (sdb_plugin_store_attribute(hostname, key, value, last_update))
+               status = -1;
        return status;
 } /* sdb_store_attribute */
 
@@ -624,6 +630,9 @@ sdb_store_service(const char *hostname, const char *name,
 
        sdb_object_deref(SDB_OBJ(host));
        pthread_rwlock_unlock(&host_lock);
+
+       if (sdb_plugin_store_service(hostname, name, last_update))
+               status = -1;
        return status;
 } /* sdb_store_service */
 
@@ -664,6 +673,10 @@ sdb_store_service_attr(const char *hostname, const char *service,
 
        sdb_object_deref(SDB_OBJ(svc));
        pthread_rwlock_unlock(&host_lock);
+
+       if (sdb_plugin_store_service_attribute(hostname, service,
+                               key, value, last_update))
+               status = -1;
        return status;
 } /* sdb_store_service_attr */
 
@@ -681,8 +694,13 @@ sdb_store_metric(const char *hostname, const char *name,
 
        if ((! hostname) || (! name))
                return -1;
-       if (store && ((! store->type) || (! store->id)))
-               return -1;
+
+       if (store) {
+               if ((store->type != NULL) != (store->id != NULL))
+                       return -1;
+               else if (! store->type)
+                       store = NULL;
+       }
 
        pthread_rwlock_wrlock(&host_lock);
        host = lookup_host(hostname, /* canonicalize = */ 1);
@@ -726,6 +744,9 @@ sdb_store_metric(const char *hostname, const char *name,
                status = -1;
        }
        pthread_rwlock_unlock(&host_lock);
+
+       if (sdb_plugin_store_metric(hostname, name, store, last_update))
+               status = -1;
        return status;
 } /* sdb_store_metric */
 
@@ -766,6 +787,10 @@ sdb_store_metric_attr(const char *hostname, const char *metric,
 
        sdb_object_deref(SDB_OBJ(m));
        pthread_rwlock_unlock(&host_lock);
+
+       if (sdb_plugin_store_metric_attribute(hostname, metric,
+                               key, value, last_update))
+               status = -1;
        return status;
 } /* sdb_store_metric_attr */
 
@@ -793,6 +818,8 @@ sdb_store_fetch_timeseries(const char *hostname, const char *metric,
 
        sdb_timeseries_t *ts;
 
+       int status = 0;
+
        if ((! hostname) || (! metric) || (! opts) || (! buf))
                return -1;
 
@@ -819,6 +846,7 @@ sdb_store_fetch_timeseries(const char *hostname, const char *metric,
                sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
                                "- no data-store configured for the stored metric",
                                hostname, metric);
+               sdb_object_deref(SDB_OBJ(m));
                pthread_rwlock_unlock(&host_lock);
                return -1;
        }
@@ -836,13 +864,14 @@ sdb_store_fetch_timeseries(const char *hostname, const char *metric,
                        sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
                                        "- %s fetcher callback returned no data for '%s'",
                                        hostname, metric, type, id);
-                       return -1;
+                       status = -1;
                }
        }
 
        ts_tojson(ts, buf);
+       sdb_object_deref(SDB_OBJ(m));
        sdb_timeseries_destroy(ts);
-       return 0;
+       return status;
 } /* sdb_store_fetch_timeseries */
 
 int
@@ -873,12 +902,18 @@ sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res)
                        tmp.data.datetime = obj->interval;
                        break;
                case SDB_FIELD_BACKEND:
-               {
+                       if (! res)
+                               return 0;
                        tmp.type = SDB_TYPE_ARRAY | SDB_TYPE_STRING;
                        tmp.data.array.length = obj->backends_num;
                        tmp.data.array.values = obj->backends;
                        return sdb_data_copy(res, &tmp);
-               }
+               case SDB_FIELD_VALUE:
+                       if (obj->type != SDB_ATTRIBUTE)
+                               return -1;
+                       if (! res)
+                               return 0;
+                       return sdb_data_copy(res, &ATTR(obj)->value);
                default:
                        return -1;
        }
@@ -928,7 +963,7 @@ int
 sdb_store_scan(int type, sdb_store_matcher_t *m, sdb_store_matcher_t *filter,
                sdb_store_lookup_cb cb, void *user_data)
 {
-       sdb_avltree_iter_t *host_iter;
+       sdb_avltree_iter_t *host_iter = NULL;
        int status = 0;
 
        if (! cb)
@@ -941,9 +976,11 @@ sdb_store_scan(int type, sdb_store_matcher_t *m, sdb_store_matcher_t *filter,
 
        pthread_rwlock_rdlock(&host_lock);
 
-       host_iter = sdb_avltree_get_iter(hosts);
-       if (! host_iter)
-               status = -1;
+       if (hosts) {
+               host_iter = sdb_avltree_get_iter(hosts);
+               if (! host_iter)
+                       status = -1;
+       }
 
        /* has_next returns false if the iterator is NULL */
        while (sdb_avltree_iter_has_next(host_iter)) {