From ac9cdb55cacd2b9ab0cc6e803a334e6b1673d2de Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Thu, 4 Oct 2007 12:26:26 +0200 Subject: [PATCH] rrdtool plugin: Use the thread-safe `librrd_th' if available. --- configure.in | 50 ++++++++--- src/Makefile.am | 4 +- src/rrdtool.c | 229 +++++++++++++++++++++++++++++++----------------- 3 files changed, 189 insertions(+), 94 deletions(-) diff --git a/configure.in b/configure.in index 54d38d58..78a807a5 100644 --- a/configure.in +++ b/configure.in @@ -670,35 +670,57 @@ m4_divert_once([HELP_WITH], [ collectd additional packages:]) # AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given]) +librrd_cflags="" +librrd_ldflags="" +librrd_threadsafe="yes" AC_ARG_WITH(rrdtool, [AS_HELP_STRING([--with-rrdtool@<:@=PREFIX@:>@], [Path to rrdtool.])], [ if test "x$withval" != "xno" && test "x$withval" != "xyes" then - LDFLAGS="$LDFLAGS -L$withval/lib" - CPPFLAGS="$CPPFLAGS -I$withval/include" + librrd_cflags="-I$withval/include" + librrd_ldflags="-L$withval/lib" with_rrdtool="yes" fi ], [with_rrdtool="yes"]) if test "x$with_rrdtool" = "xyes" then - AC_CHECK_LIB(rrd, rrd_update, - [ - AC_DEFINE(HAVE_LIBRRD, 1, [Define to 1 if you have the rrd library (-lrrd).]) - ], - [with_rrdtool="no (librrd not found)"], [-lm]) + SAVE_CFLAGS="$CFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS $librrd_cflags" + LDFLAGS="$LDFLAGS $librrd_ldflags" + + AC_CHECK_HEADERS(rrd.h,, [with_rrdtool="no (rrd.h not found)"]) + + CFLAGS="$SAVE_CFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi if test "x$with_rrdtool" = "xyes" then - AC_CHECK_HEADERS(rrd.h,, [with_rrdtool="no (rrd.h not found)"]) + AC_CHECK_LIB(rrd_th, rrd_update_r, + [with_rrdtool="yes" + librrd_ldflags="$librrd_ldflags -lrrd_th -lm" + ], + [librrd_threadsafe="no" + AC_CHECK_LIB(rrd, rrd_update, + [with_rrdtool="yes" + librrd_ldflags="$librrd_ldflags -lrrd -lm" + ], + [with_rrdtool="no (symbol 'rrd_update' not found)"], + [-lm]) + ] + [-lm]) fi if test "x$with_rrdtool" = "xyes" then - collect_rrdtool=1 -else - collect_rrdtool=0 + BUILD_WITH_LIBRRD_CFLAGS="$librrd_cflags" + BUILD_WITH_LIBRRD_LDFLAGS="$librrd_ldflags" + AC_SUBST(BUILD_WITH_LIBRRD_CFLAGS) + AC_SUBST(BUILD_WITH_LIBRRD_LDFLAGS) +fi +if test "x$librrd_threadsafe" = "xyes" +then + AC_DEFINE(HAVE_THREADSAFE_LIBRRD, 1, [Define to 1 if you have the threadsafe rrd library (-lrrd_th).]) fi -AC_DEFINE_UNQUOTED(COLLECT_RRDTOOL, [$collect_rrdtool], - [Wether or not to use rrdtool library]) -AM_CONDITIONAL(BUILD_WITH_RRDTOOL, test "x$with_rrdtool" = "xyes") AC_ARG_WITH(libpthread, [AS_HELP_STRING([--with-libpthread=@<:@=PREFIX@:>@], [Path to libpthread.])], [ if test "x$withval" != "xno" -a "x$withval" != "xyes" diff --git a/src/Makefile.am b/src/Makefile.am index f988a0f0..98185804 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -438,7 +438,9 @@ endif if BUILD_PLUGIN_RRDTOOL pkglib_LTLIBRARIES += rrdtool.la rrdtool_la_SOURCES = rrdtool.c -rrdtool_la_LDFLAGS = -module -avoid-version -lrrd +rrdtool_la_LDFLAGS = -module -avoid-version +rrdtool_la_CFLAGS = $(BUILD_WITH_LIBRRD_CFLAGS) +rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS) collectd_LDADD += "-dlopen" rrdtool.la collectd_DEPENDENCIES += rrdtool.la endif diff --git a/src/rrdtool.c b/src/rrdtool.c index 56ef581e..14087c92 100644 --- a/src/rrdtool.c +++ b/src/rrdtool.c @@ -112,6 +112,10 @@ static pthread_t queue_thread = 0; static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER; +#if !HAVE_THREADSAFE_LIBRRD +static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + static int do_shutdown = 0; /* * * * * * * * * * @@ -327,6 +331,143 @@ static int ds_get (char ***ret, const data_set_t *ds, const value_list_t *vl) return (ds_num); } +#if HAVE_THREADSAFE_LIBRRD +static int srrd_create (char *filename, unsigned long pdp_step, time_t last_up, + int argc, char **argv) +{ + int status; + + optind = 0; /* bug in librrd? */ + rrd_clear_error (); + + status = rrd_create_r (filename, pdp_step, last_up, argc, argv); + + if (status != 0) + { + WARNING ("rrdtool plugin: rrd_create_r (%s) failed: %s", + filename, rrd_get_error ()); + } + + return (status); +} /* int srrd_create */ + +static int srrd_update (char *filename, char *template, int argc, char **argv) +{ + int status; + + optind = 0; /* bug in librrd? */ + rrd_clear_error (); + + status = rrd_update_r (filename, template, argc, argv); + + if (status != 0) + { + WARNING ("rrdtool plugin: rrd_update_r (%s) failed: %s", + filename, rrd_get_error ()); + } + + return (status); +} /* int srrd_update */ +/* #endif HAVE_THREADSAFE_LIBRRD */ + +#else /* !HAVE_THREADSAFE_LIBRRD */ +static int srrd_create (char *filename, unsigned long pdp_step, time_t last_up, + int argc, char **argv) +{ + int status; + + int new_argc; + char **new_argv; + + char pdp_step_str[16]; + char last_up_str[16]; + + new_argc = 6 + argc; + new_argv = (char **) malloc ((new_argc + 1) * sizeof (char *)); + if (new_argv == NULL) + { + ERROR ("rrdtool plugin: malloc failed."); + return (-1); + } + + if (last_up == 0) + last_up = time (NULL) - 10; + + snprintf (pdp_step_str, sizeof (pdp_step_str), "%lu", pdp_step); + pdp_step_str[sizeof (pdp_step_str) - 1] = '\0'; + snprintf (last_up_str, sizeof (last_up_str), "%u", (unsigned int) last_up); + last_up_str[sizeof (last_up_str) - 1] = '\0'; + + new_argv[0] = "create"; + new_argv[1] = filename; + new_argv[2] = "-s"; + new_argv[3] = pdp_step_str; + new_argv[4] = "-b"; + new_argv[5] = last_up_str; + + memcpy (new_argv + 6, argv, argc * sizeof (char *)); + new_argv[new_argc] = NULL; + + pthread_mutex_lock (&librrd_lock); + optind = 0; /* bug in librrd? */ + rrd_clear_error (); + + status = rrd_create (new_argc, new_argv); + pthread_mutex_unlock (&librrd_lock); + + if (status != 0) + { + WARNING ("rrdtool plugin: rrd_create (%s) failed: %s", + filename, rrd_get_error ()); + } + + sfree (new_argv); + + return (status); +} /* int srrd_create */ + +static int srrd_update (char *filename, char *template, int argc, char **argv) +{ + int status; + + int new_argc; + char **new_argv; + + assert (template == NULL); + + new_argc = 2 + argc; + new_argv = (char **) malloc ((new_argc + 1) * sizeof (char *)); + if (new_argv == NULL) + { + ERROR ("rrdtool plugin: malloc failed."); + return (-1); + } + + new_argv[0] = "update"; + new_argv[1] = filename; + + memcpy (new_argv + 2, argv, argc * sizeof (char *)); + new_argv[new_argc] = NULL; + + pthread_mutex_lock (&librrd_lock); + optind = 0; /* bug in librrd? */ + rrd_clear_error (); + + status = rrd_update (argc, argv); + pthread_mutex_unlock (&librrd_lock); + + if (status != 0) + { + WARNING ("rrdtool plugin: rrd_update_r failed: %s: %s", + argv[1], rrd_get_error ()); + } + + sfree (new_argv); + + return (status); +} /* int srrd_update */ +#endif /* !HAVE_THREADSAFE_LIBRRD */ + static int rrd_create_file (char *filename, const data_set_t *ds, const value_list_t *vl) { char **argv; @@ -336,8 +477,6 @@ static int rrd_create_file (char *filename, const data_set_t *ds, const value_li char **ds_def; int ds_num; int i, j; - char stepsize_str[16]; - char begin_str[16]; int status = 0; if (check_create_dir (filename)) @@ -355,7 +494,7 @@ static int rrd_create_file (char *filename, const data_set_t *ds, const value_li return (-1); } - argc = ds_num + rra_num + 6; + argc = ds_num + rra_num; if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL) { @@ -365,47 +504,15 @@ static int rrd_create_file (char *filename, const data_set_t *ds, const value_li return (-1); } - status = snprintf (stepsize_str, sizeof (stepsize_str), - "%i", (stepsize > 0) ? stepsize : vl->interval); - if ((status < 1) || (status >= sizeof (stepsize_str))) - { - ERROR ("rrdtool plugin: snprintf failed."); - free (argv); - ds_free (ds_num, ds_def); - rra_free (rra_num, rra_def); - return (-1); - } + memcpy (argv, ds_def, ds_num * sizeof (char *)); + memcpy (argv + ds_num, rra_def, rra_num * sizeof (char *)); + argv[ds_num + rra_num] = NULL; assert (vl->time > 10); - status = snprintf (begin_str, sizeof (begin_str), - "%llu", (unsigned long long) (vl->time - 10)); - if ((status < 1) || (status >= sizeof (begin_str))) - { - ERROR ("rrdtool plugin: snprintf failed."); - return (-1); - } - - argv[0] = "create"; - argv[1] = filename; - argv[2] = "-b"; - argv[3] = begin_str; - argv[4] = "-s"; - argv[5] = stepsize_str; - - j = 6; - for (i = 0; i < ds_num; i++) - argv[j++] = ds_def[i]; - for (i = 0; i < rra_num; i++) - argv[j++] = rra_def[i]; - argv[j] = NULL; - - optind = 0; /* bug in librrd? */ - rrd_clear_error (); - if (rrd_create (argc, argv) == -1) - { - ERROR ("rrd_create failed: %s: %s", filename, rrd_get_error ()); - status = -1; - } + status = srrd_create (filename, + (stepsize > 0) ? stepsize : vl->interval, + vl->time - 10, + argc, argv); free (argv); ds_free (ds_num, ds_def); @@ -494,42 +601,6 @@ static int value_list_to_filename (char *buffer, int buffer_len, return (0); } /* int value_list_to_filename */ -static int rrd_write_to_file (char *filename, char **values, int values_num) -{ - char **argv; - int argc; - int status; - - if (values_num < 1) - return (0); - - argc = values_num + 2; - argv = (char **) malloc ((argc + 1) * sizeof (char *)); - if (argv == NULL) - return (-1); - - argv[0] = "update"; - argv[1] = filename; - memcpy (argv + 2, values, values_num * sizeof (char *)); - argv[argc] = NULL; - - DEBUG ("rrd_update (argc = %i, argv = %p)", argc, (void *) argv); - - optind = 0; /* bug in librrd? */ - rrd_clear_error (); - status = rrd_update (argc, argv); - if (status != 0) - { - WARNING ("rrd_update failed: %s: %s", - filename, rrd_get_error ()); - status = -1; - } - - sfree (argv); - - return (status); -} /* int rrd_write_cache_entry */ - static void *rrd_queue_thread (void *data) { while (42) @@ -581,7 +652,7 @@ static void *rrd_queue_thread (void *data) pthread_mutex_unlock (&cache_lock); /* Write the values to the RRD-file */ - rrd_write_to_file (queue_entry->filename, values, values_num); + srrd_update (queue_entry->filename, NULL, values_num, values); for (i = 0; i < values_num; i++) { -- 2.30.2