diff --git a/src/utils_cache.c b/src/utils_cache.c
index 224748f2e65b714c1318d846072147c13f048605..b2f2c36b7223b87b53266ed121c3bdc9bc1a27ed 100644 (file)
--- a/src/utils_cache.c
+++ b/src/utils_cache.c
/**
* collectd - src/utils_cache.c
/**
* collectd - src/utils_cache.c
- * Copyright (C) 2007 Florian octo Forster
+ * Copyright (C) 2007,2008 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
return (-1);
}
return (-1);
}
- snprintf (n.message, sizeof (n.message),
+ ssnprintf (n.message, sizeof (n.message),
"%s has not been updated for %i seconds.", name,
(int) (n.time - ce->last_update));
pthread_mutex_unlock (&cache_lock);
"%s has not been updated for %i seconds.", name,
(int) (n.time - ce->last_update));
pthread_mutex_unlock (&cache_lock);
- n.message[sizeof (n.message) - 1] = '\0';
plugin_dispatch_notification (&n);
return (0);
plugin_dispatch_notification (&n);
return (0);
ce = cache_alloc (ds->ds_num);
if (ce == NULL)
{
ce = cache_alloc (ds->ds_num);
if (ce == NULL)
{
+ sfree (key_copy);
ERROR ("uc_insert: cache_alloc (%i) failed.", ds->ds_num);
return (-1);
}
ERROR ("uc_insert: cache_alloc (%i) failed.", ds->ds_num);
return (-1);
}
{
ERROR ("uc_purge: realloc failed.");
c_avl_iterator_destroy (iter);
{
ERROR ("uc_purge: realloc failed.");
c_avl_iterator_destroy (iter);
+ pthread_mutex_unlock (&cache_lock);
return (-1);
}
return (-1);
}
ERROR ("uc_check_timeout: c_avl_remove (%s) failed.", keys[i]);
}
sfree (keys[i]);
ERROR ("uc_check_timeout: c_avl_remove (%s) failed.", keys[i]);
}
sfree (keys[i]);
+ sfree (key);
cache_free (ce);
}
else if (status == 1) /* persist */
{
DEBUG ("uc_check_timeout: %s is missing, sending notification.",
keys[i]);
cache_free (ce);
}
else if (status == 1) /* persist */
{
DEBUG ("uc_check_timeout: %s is missing, sending notification.",
keys[i]);
- ce->state = STATE_ERROR;
+ ce->state = STATE_MISSING;
}
else if (status == 2) /* do not persist */
{
}
else if (status == 2) /* do not persist */
{
- if (ce->state == STATE_ERROR)
+ if (ce->state == STATE_MISSING)
{
DEBUG ("uc_check_timeout: %s is missing but "
"notification has already been sent.",
keys[i]);
sfree (keys[i]);
}
{
DEBUG ("uc_check_timeout: %s is missing but "
"notification has already been sent.",
keys[i]);
sfree (keys[i]);
}
- else /* (ce->state != STATE_ERROR) */
+ else /* (ce->state != STATE_MISSING) */
{
DEBUG ("uc_check_timeout: %s is missing, sending one notification.",
keys[i]);
{
DEBUG ("uc_check_timeout: %s is missing, sending one notification.",
keys[i]);
- ce->state = STATE_ERROR;
+ ce->state = STATE_MISSING;
}
}
else
{
}
}
else
{
- WARNING ("uc_check_timeout: ut_check_interesting (%s) returned ",
+ WARNING ("uc_check_timeout: ut_check_interesting (%s) returned "
"invalid status %i.",
keys[i], status);
}
"invalid status %i.",
keys[i], status);
}
/* Send a notification (after the lock has been released) if we switch the
* state from something else to `okay'. */
/* Send a notification (after the lock has been released) if we switch the
* state from something else to `okay'. */
- if (ce->state != STATE_OKAY)
+ if (ce->state == STATE_MISSING)
{
send_okay_notification = 1;
ce->state = STATE_OKAY;
{
send_okay_notification = 1;
ce->state = STATE_OKAY;
n.severity = NOTIF_OKAY;
n.time = vl->time;
n.severity = NOTIF_OKAY;
n.time = vl->time;
- snprintf (n.message, sizeof (n.message),
+ ssnprintf (n.message, sizeof (n.message),
"Received a value for %s. It was missing for %u seconds.",
name, (unsigned int) update_delay);
"Received a value for %s. It was missing for %u seconds.",
name, (unsigned int) update_delay);
- n.message[sizeof (n.message) - 1] = '\0';
plugin_dispatch_notification (&n);
return (0);
} /* int uc_update */
plugin_dispatch_notification (&n);
return (0);
} /* int uc_update */
-gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
+int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num)
{
{
- char name[6 * DATA_MAX_NAME_LEN];
gauge_t *ret = NULL;
gauge_t *ret = NULL;
+ size_t ret_num = 0;
cache_entry_t *ce = NULL;
cache_entry_t *ce = NULL;
-
- if (FORMAT_VL (name, sizeof (name), vl, ds) != 0)
- {
- ERROR ("uc_get_rate: FORMAT_VL failed.");
- return (NULL);
- }
+ int status = 0;
pthread_mutex_lock (&cache_lock);
if (c_avl_get (cache_tree, name, (void *) &ce) == 0)
{
assert (ce != NULL);
pthread_mutex_lock (&cache_lock);
if (c_avl_get (cache_tree, name, (void *) &ce) == 0)
{
assert (ce != NULL);
- assert (ce->values_num == ds->ds_num);
- ret = (gauge_t *) malloc (ce->values_num * sizeof (gauge_t));
+ ret_num = ce->values_num;
+ ret = (gauge_t *) malloc (ret_num * sizeof (gauge_t));
if (ret == NULL)
{
if (ret == NULL)
{
- ERROR ("uc_get_rate: malloc failed.");
+ ERROR ("utils_cache: uc_get_rate_by_name: malloc failed.");
+ status = -1;
}
else
{
}
else
{
- memcpy (ret, ce->values_gauge, ce->values_num * sizeof (gauge_t));
+ memcpy (ret, ce->values_gauge, ret_num * sizeof (gauge_t));
}
}
}
}
+ else
+ {
+ DEBUG ("utils_cache: uc_get_rate_by_name: No such value: %s", name);
+ status = -1;
+ }
pthread_mutex_unlock (&cache_lock);
pthread_mutex_unlock (&cache_lock);
+ if (status == 0)
+ {
+ *ret_values = ret;
+ *ret_values_num = ret_num;
+ }
+
+ return (status);
+} /* gauge_t *uc_get_rate_by_name */
+
+gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
+{
+ char name[6 * DATA_MAX_NAME_LEN];
+ gauge_t *ret = NULL;
+ size_t ret_num = 0;
+ int status;
+
+ if (FORMAT_VL (name, sizeof (name), vl, ds) != 0)
+ {
+ ERROR ("uc_insert: FORMAT_VL failed.");
+ return (NULL);
+ }
+
+ status = uc_get_rate_by_name (name, &ret, &ret_num);
+ if (status != 0)
+ return (NULL);
+
+ /* This is important - the caller has no other way of knowing how many
+ * values are returned. */
+ if (ret_num != (size_t) ds->ds_num)
+ {
+ ERROR ("utils_cache: uc_get_rate: ds[%s] has %i values, "
+ "but uc_get_rate_by_name returned %zu.",
+ ds->type, ds->ds_num, ret_num);
+ sfree (ret);
+ return (NULL);
+ }
+
return (ret);
} /* gauge_t *uc_get_rate */
return (ret);
} /* gauge_t *uc_get_rate */
+int uc_get_names (char ***ret_names, time_t **ret_times, size_t *ret_number)
+{
+ c_avl_iterator_t *iter;
+ char *key;
+ cache_entry_t *value;
+
+ char **names = NULL;
+ time_t *times = NULL;
+ size_t number = 0;
+
+ int status = 0;
+
+ if ((ret_names == NULL) || (ret_number == NULL))
+ return (-1);
+
+ pthread_mutex_lock (&cache_lock);
+
+ iter = c_avl_get_iterator (cache_tree);
+ while (c_avl_iterator_next (iter, (void *) &key, (void *) &value) == 0)
+ {
+ char **temp;
+
+ if (ret_times != NULL)
+ {
+ time_t *tmp_times;
+
+ tmp_times = (time_t *) realloc (times, sizeof (time_t) * (number + 1));
+ if (tmp_times == NULL)
+ {
+ status = -1;
+ break;
+ }
+ times = tmp_times;
+ times[number] = value->last_time;
+ }
+
+ temp = (char **) realloc (names, sizeof (char *) * (number + 1));
+ if (temp == NULL)
+ {
+ status = -1;
+ break;
+ }
+ names = temp;
+ names[number] = strdup (key);
+ if (names[number] == NULL)
+ {
+ status = -1;
+ break;
+ }
+ number++;
+ } /* while (c_avl_iterator_next) */
+
+ c_avl_iterator_destroy (iter);
+ pthread_mutex_unlock (&cache_lock);
+
+ if (status != 0)
+ {
+ size_t i;
+
+ for (i = 0; i < number; i++)
+ {
+ sfree (names[i]);
+ }
+ sfree (names);
+
+ return (-1);
+ }
+
+ *ret_names = names;
+ if (ret_times != NULL)
+ *ret_times = times;
+ *ret_number = number;
+
+ return (0);
+} /* int uc_get_names */
+
int uc_get_state (const data_set_t *ds, const value_list_t *vl)
{
char name[6 * DATA_MAX_NAME_LEN];
int uc_get_state (const data_set_t *ds, const value_list_t *vl)
{
char name[6 * DATA_MAX_NAME_LEN];
cache_entry_t *ce = NULL;
int ret = -1;
cache_entry_t *ce = NULL;
int ret = -1;
- if (state < STATE_OKAY)
- state = STATE_OKAY;
- if (state > STATE_ERROR)
- state = STATE_ERROR;
-
if (FORMAT_VL (name, sizeof (name), vl, ds) != 0)
{
ERROR ("uc_get_state: FORMAT_VL failed.");
if (FORMAT_VL (name, sizeof (name), vl, ds) != 0)
{
ERROR ("uc_get_state: FORMAT_VL failed.");