X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrdtool.c;h=7cf243671254cf261b77fe3e79d21885f321384e;hb=92445ff3363441d0f515de4a3ab92a504cfc0366;hp=6b9c5404c736c3bb9561bb9ff7d4946acf709a1b;hpb=47faf00c18402cefd0e195d63ad48d5e7e6a4a92;p=collectd.git diff --git a/src/rrdtool.c b/src/rrdtool.c index 6b9c5404..7cf24367 100644 --- a/src/rrdtool.c +++ b/src/rrdtool.c @@ -1,6 +1,6 @@ /** * collectd - src/rrdtool.c - * Copyright (C) 2006,2007 Florian octo Forster + * Copyright (C) 2006-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 @@ -47,6 +47,13 @@ struct rrd_cache_s }; typedef struct rrd_cache_s rrd_cache_t; +enum rrd_queue_dir_e +{ + QUEUE_INSERT_FRONT, + QUEUE_INSERT_BACK +}; +typedef enum rrd_queue_dir_e rrd_queue_dir_t; + struct rrd_queue_s { char *filename; @@ -284,12 +291,16 @@ static int ds_get (char ***ret, const data_set_t *ds, const value_list_t *vl) } if (isnan (d->min)) - strcpy (min, "U"); + { + sstrncpy (min, "U", sizeof (min)); + } else ssnprintf (min, sizeof (min), "%lf", d->min); if (isnan (d->max)) - strcpy (max, "U"); + { + sstrncpy (max, "U", sizeof (max)); + } else ssnprintf (max, sizeof (max), "%lf", d->max); @@ -325,14 +336,14 @@ static int ds_get (char ***ret, const data_set_t *ds, const value_list_t *vl) #if HAVE_THREADSAFE_LIBRRD static int srrd_create (char *filename, unsigned long pdp_step, time_t last_up, - int argc, char **argv) + int argc, const char **argv) { int status; optind = 0; /* bug in librrd? */ rrd_clear_error (); - status = rrd_create_r (filename, pdp_step, last_up, argc, argv); + status = rrd_create_r (filename, pdp_step, last_up, argc, (void *) argv); if (status != 0) { @@ -343,14 +354,15 @@ static int srrd_create (char *filename, unsigned long pdp_step, time_t last_up, return (status); } /* int srrd_create */ -static int srrd_update (char *filename, char *template, int argc, char **argv) +static int srrd_update (char *filename, char *template, + int argc, const char **argv) { int status; optind = 0; /* bug in librrd? */ rrd_clear_error (); - status = rrd_update_r (filename, template, argc, argv); + status = rrd_update_r (filename, template, argc, (void *) argv); if (status != 0) { @@ -364,7 +376,7 @@ static int srrd_update (char *filename, char *template, int argc, char **argv) #else /* !HAVE_THREADSAFE_LIBRRD */ static int srrd_create (char *filename, unsigned long pdp_step, time_t last_up, - int argc, char **argv) + int argc, const char **argv) { int status; @@ -416,7 +428,8 @@ static int srrd_create (char *filename, unsigned long pdp_step, time_t last_up, return (status); } /* int srrd_create */ -static int srrd_update (char *filename, char *template, int argc, char **argv) +static int srrd_update (char *filename, char *template, + int argc, const char **argv) { int status; @@ -501,7 +514,7 @@ static int rrd_create_file (char *filename, const data_set_t *ds, const value_li status = srrd_create (filename, (stepsize > 0) ? stepsize : vl->interval, vl->time - 10, - argc, argv); + argc, (const char **)argv); free (argv); ds_free (ds_num, ds_def); @@ -641,7 +654,8 @@ static void *rrd_queue_thread (void *data) pthread_mutex_unlock (&cache_lock); /* Write the values to the RRD-file */ - srrd_update (queue_entry->filename, NULL, values_num, values); + srrd_update (queue_entry->filename, NULL, + values_num, (const char **)values); DEBUG ("rrdtool plugin: queue thread: Wrote %i values to %s", values_num, queue_entry->filename); @@ -663,37 +677,74 @@ static void *rrd_queue_thread (void *data) return ((void *) 0); } /* void *rrd_queue_thread */ -static int rrd_queue_cache_entry (const char *filename) +static int rrd_queue_cache_entry (const char *filename, rrd_queue_dir_t dir) { - rrd_queue_t *queue_entry; + rrd_queue_t *queue_entry; - queue_entry = (rrd_queue_t *) malloc (sizeof (rrd_queue_t)); - if (queue_entry == NULL) - return (-1); + queue_entry = (rrd_queue_t *) malloc (sizeof (rrd_queue_t)); + if (queue_entry == NULL) + return (-1); - queue_entry->filename = strdup (filename); - if (queue_entry->filename == NULL) - { - free (queue_entry); - return (-1); - } + queue_entry->filename = strdup (filename); + if (queue_entry->filename == NULL) + { + free (queue_entry); + return (-1); + } - queue_entry->next = NULL; + queue_entry->next = NULL; - pthread_mutex_lock (&queue_lock); - if (queue_tail == NULL) - queue_head = queue_entry; - else - queue_tail->next = queue_entry; - queue_tail = queue_entry; - pthread_cond_signal (&queue_cond); - pthread_mutex_unlock (&queue_lock); + pthread_mutex_lock (&queue_lock); + if (dir == QUEUE_INSERT_FRONT) + { + queue_entry->next = queue_head; + queue_head = queue_entry; + if (queue_tail == NULL) + queue_tail = queue_head; + } + else /* (dir == QUEUE_INSERT_BACK) */ + { + if (queue_tail == NULL) + queue_head = queue_entry; + else + queue_tail->next = queue_entry; + queue_tail = queue_entry; + } + pthread_cond_signal (&queue_cond); + pthread_mutex_unlock (&queue_lock); - DEBUG ("rrdtool plugin: Put `%s' into the update queue", filename); + DEBUG ("rrdtool plugin: Put `%s' into the update queue", filename); - return (0); + return (0); } /* int rrd_queue_cache_entry */ +static int rrd_queue_move_to_front (const char *filename) +{ + rrd_queue_t *this; + rrd_queue_t *prev; + + this = NULL; + prev = NULL; + pthread_mutex_lock (&queue_lock); + for (this = queue_head; this != NULL; this = this->next) + { + if (strcmp (this->filename, filename) == 0) + break; + prev = this; + } + + /* Check if we found the entry and if it is NOT the first entry. */ + if ((this != NULL) && (prev != NULL)) + { + prev->next = this->next; + this->next = queue_head; + queue_head = this; + } + pthread_mutex_unlock (&queue_lock); + + return (0); +} /* int rrd_queue_move_to_front */ + static void rrd_cache_flush (int timeout) { rrd_cache_t *rc; @@ -720,7 +771,7 @@ static void rrd_cache_flush (int timeout) continue; else if (rc->values_num > 0) { - if (rrd_queue_cache_entry (key) == 0) + if (rrd_queue_cache_entry (key, QUEUE_INSERT_BACK) == 0) rc->flags = FLAG_QUEUED; } else /* ancient and no values -> waste of memory */ @@ -771,8 +822,7 @@ static int rrd_cache_flush_identifier (int timeout, const char *identifier) rrd_cache_t *rc; time_t now; int status; - char *key; - size_t key_size; + char key[2048]; if (identifier == NULL) { @@ -782,15 +832,13 @@ static int rrd_cache_flush_identifier (int timeout, const char *identifier) now = time (NULL); - key_size = strlen (identifier + 5) * sizeof (char); - key = (char *) malloc (key_size); - if (key == NULL) - { - ERROR ("rrdtool plugin: rrd_cache_flush_identifier: malloc failed."); - return (-1); - } - snprintf (key, key_size, "%s.rrd", identifier); - key[key_size - 1] = 0; + if (datadir == NULL) + snprintf (key, sizeof (key), "%s.rrd", + identifier); + else + snprintf (key, sizeof (key), "%s/%s.rrd", + datadir, identifier); + key[sizeof (key) - 1] = 0; status = c_avl_get (cache, key, (void *) &rc); if (status != 0) @@ -802,12 +850,12 @@ static int rrd_cache_flush_identifier (int timeout, const char *identifier) } if (rc->flags == FLAG_QUEUED) - status = 0; + status = rrd_queue_move_to_front (key); else if ((now - rc->first_value) < timeout) status = 0; else if (rc->values_num > 0) { - status = rrd_queue_cache_entry (key); + status = rrd_queue_cache_entry (key, QUEUE_INSERT_FRONT); if (status == 0) rc->flags = FLAG_QUEUED; } @@ -901,9 +949,9 @@ static int rrd_cache_insert (const char *filename, } DEBUG ("rrdtool plugin: rrd_cache_insert: file = %s; " - "values_num = %i; age = %u;", + "values_num = %i; age = %lu;", filename, rc->values_num, - rc->last_value - rc->first_value); + (unsigned long)(rc->last_value - rc->first_value)); if ((rc->last_value - rc->first_value) >= cache_timeout) { @@ -911,7 +959,7 @@ static int rrd_cache_insert (const char *filename, * the same time, ALWAYS lock `cache_lock' first! */ if (rc->flags != FLAG_QUEUED) { - if (rrd_queue_cache_entry (filename) == 0) + if (rrd_queue_cache_entry (filename, QUEUE_INSERT_BACK) == 0) rc->flags = FLAG_QUEUED; } else