Code

rrdtool plugin: Use the thread-safe `librrd_th' if available.
authorFlorian Forster <octo@huhu.verplant.org>
Thu, 4 Oct 2007 10:26:26 +0000 (12:26 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Thu, 4 Oct 2007 10:26:26 +0000 (12:26 +0200)
configure.in
src/Makefile.am
src/rrdtool.c

index 54d38d5882d3bc1c666c7f0e1d134b2fbb4f7ae4..78a807a5a0582c700d898b6aff5c9467f39f6399 100644 (file)
@@ -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"
index f988a0f0f30649ba154db4878c1bc3ce06905a0e..9818580462860123c3640a65ce81789858f3e683 100644 (file)
@@ -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
index 56ef581e3596a522656380da219f408bec0dce43..14087c92deff23d023145404ee0bcdb96b14b089 100644 (file)
@@ -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++)
                {