Merge branch 'ff/highres'
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Wed, 17 Nov 2010 14:18:03 +0000 (15:18 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Wed, 17 Nov 2010 14:20:11 +0000 (15:20 +0100)
Conflicts:
src/netapp.c

57 files changed:
bindings/java/org/collectd/api/CollectdFlushInterface.java
bindings/java/org/collectd/api/ValueList.java
configure.in
src/Makefile.am
src/bind.c
src/collectd.c
src/collectd.h
src/common.c
src/configfile.c
src/configfile.h
src/cpu.c
src/cpython.h
src/csv.c
src/dbi.c
src/dns.c
src/exec.c
src/gmond.c
src/ipmi.c
src/ipvs.c
src/java.c
src/libvirt.c
src/logfile.c
src/match_timediff.c
src/memcached.c
src/modbus.c
src/mysql.c
src/netapp.c
src/network.c
src/network.h
src/notify_email.c
src/onewire.c
src/oracle.c
src/perl.c
src/plugin.c
src/plugin.h
src/postgresql.c
src/powerdns.c
src/python.c
src/pyvalues.c
src/rrdcached.c
src/rrdtool.c
src/snmp.c
src/target_notification.c
src/target_scale.c
src/thermal.c
src/utils_cache.c
src/utils_cache.h
src/utils_cmd_flush.c
src/utils_cmd_listval.c
src/utils_cmd_putval.c
src/utils_db_query.c
src/utils_db_query.h
src/utils_format_json.c
src/utils_rrdcreate.c
src/utils_time.c [new file with mode: 0644]
src/utils_time.h [new file with mode: 0644]
src/write_http.c

index 3e492dd..410c61c 100644 (file)
@@ -29,5 +29,5 @@ package org.collectd.api;
  */
 public interface CollectdFlushInterface
 {
-       public int flush (int timeout, String identifier);
+       public int flush (Number timeout, String identifier);
 }
index 1baeff2..b8d6f40 100644 (file)
@@ -87,10 +87,16 @@ public class ValueList extends PluginData {
         _ds = new DataSet (_type, dsrc);
     }
 
+    /**
+     * Returns the interval (in milliseconds) of the value list.
+     */
     public long getInterval() {
         return _interval;
     }
 
+    /**
+     * Sets the interval (in milliseconds) of the value list.
+     */
     public void setInterval(long interval) {
         _interval = interval;
     }
index 5d82c47..fd6a257 100644 (file)
@@ -572,6 +572,16 @@ socket_needs_socket="no"
 AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB(socket, socket, [socket_needs_socket="yes"], AC_MSG_ERROR(cannot find socket)))
 AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes")
 
+clock_gettime_needs_rt="no"
+clock_gettime_needs_posix4="no"
+AC_CHECK_FUNCS(clock_gettime,
+    [],
+    AC_CHECK_LIB(rt, clock_gettime,
+        [clock_gettime_needs_rt="yes"],
+        AC_CHECK_LIB(posix4, clock_gettime,
+            [clock_gettime_needs_posix4="yes"],
+            AC_MSG_ERROR(cannot find clock_gettime))))
+
 nanosleep_needs_rt="no"
 nanosleep_needs_posix4="no"
 AC_CHECK_FUNCS(nanosleep,
@@ -581,8 +591,9 @@ AC_CHECK_FUNCS(nanosleep,
         AC_CHECK_LIB(posix4, nanosleep,
             [nanosleep_needs_posix4="yes"],
             AC_MSG_ERROR(cannot find nanosleep))))
-AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$nanosleep_needs_rt" = "xyes")
-AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$nanosleep_needs_posix4" = "xyes")
+
+AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes")
+AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes")
 
 AC_CHECK_FUNCS(sysctl, [have_sysctl="yes"], [have_sysctl="no"])
 AC_CHECK_FUNCS(sysctlbyname, [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
index 247892b..1a7ba5b 100644 (file)
@@ -41,6 +41,7 @@ collectd_SOURCES = collectd.c collectd.h \
                   utils_subst.c utils_subst.h \
                   utils_tail.c utils_tail.h \
                   utils_threshold.c utils_threshold.h \
+                  utils_time.c utils_time.h \
                   types_list.c types_list.h
 
 collectd_CPPFLAGS =  $(AM_CPPFLAGS) $(LTDLINCL)
index 6e0b907..47215c7 100644 (file)
@@ -241,7 +241,7 @@ static void submit (time_t ts, const char *plugin_instance, /* {{{ */
 
   vl.values = values;
   vl.values_len = 1;
-  vl.time = ts;
+  vl.time = TIME_T_TO_CDTIME_T (ts);
   sstrncpy(vl.host, hostname_g, sizeof(vl.host));
   sstrncpy(vl.plugin, "bind", sizeof(vl.plugin));
   if (plugin_instance) {
index 277d3b0..d33d1d6 100644 (file)
@@ -40,7 +40,7 @@
  * Global variables
  */
 char hostname_g[DATA_MAX_NAME_LEN];
-int  interval_g;
+cdtime_t interval_g;
 int  timeout_g;
 #if HAVE_LIBKSTAT
 kstat_ctl_t *kc;
@@ -51,7 +51,9 @@ static int loop = 0;
 static void *do_flush (void __attribute__((unused)) *arg)
 {
        INFO ("Flushing all data.");
-       plugin_flush (NULL, -1, NULL);
+       plugin_flush (/* plugin = */ NULL,
+                       /* timeout = */ 0,
+                       /* ident = */ NULL);
        INFO ("Finished flushing all data.");
        pthread_exit (NULL);
        return NULL;
@@ -139,15 +141,25 @@ static int init_global_variables (void)
 
        str = global_option_get ("Interval");
        if (str == NULL)
-               str = "10";
-       interval_g = atoi (str);
-       if (interval_g <= 0)
        {
-               fprintf (stderr, "Cannot set the interval to a correct value.\n"
-                               "Please check your settings.\n");
-               return (-1);
+               interval_g = TIME_T_TO_CDTIME_T (10);
+       }
+       else
+       {
+               double tmp;
+
+               tmp = atof (str);
+               if (tmp <= 0.0)
+               {
+                       fprintf (stderr, "Cannot set the interval to a "
+                                       "correct value.\n"
+                                       "Please check your settings.\n");
+                       return (-1);
+               }
+
+               interval_g = DOUBLE_TO_CDTIME_T (tmp);
        }
-       DEBUG ("interval_g = %i;", interval_g);
+       DEBUG ("interval_g = %.3f;", CDTIME_T_TO_DOUBLE (interval_g));
 
        str = global_option_get ("Timeout");
        if (str == NULL)
@@ -311,22 +323,14 @@ static int do_init (void)
 
 static int do_loop (void)
 {
-       struct timeval tv_now;
-       struct timeval tv_next;
-       struct timeval tv_wait;
-       struct timespec ts_wait;
+       cdtime_t wait_until;
+
+       wait_until = cdtime () + interval_g;
 
        while (loop == 0)
        {
-               if (gettimeofday (&tv_next, NULL) < 0)
-               {
-                       char errbuf[1024];
-                       ERROR ("gettimeofday failed: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       return (-1);
-               }
-               tv_next.tv_sec += interval_g;
+               struct timespec ts_wait = { 0, 0 };
+               cdtime_t now;
 
 #if HAVE_LIBKSTAT
                update_kstat ();
@@ -335,27 +339,20 @@ static int do_loop (void)
                /* Issue all plugins */
                plugin_read_all ();
 
-               if (gettimeofday (&tv_now, NULL) < 0)
-               {
-                       char errbuf[1024];
-                       ERROR ("gettimeofday failed: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       return (-1);
-               }
-
-               if (timeval_cmp (tv_next, tv_now, &tv_wait) <= 0)
+               now = cdtime ();
+               if (now >= wait_until)
                {
                        WARNING ("Not sleeping because the next interval is "
-                                       "%i.%06i seconds in the past!",
-                                       (int) tv_wait.tv_sec, (int) tv_wait.tv_usec);
+                                       "%.3f seconds in the past!",
+                                       CDTIME_T_TO_DOUBLE (now - wait_until));
+                       wait_until = now + interval_g;
                        continue;
                }
 
-               ts_wait.tv_sec  = tv_wait.tv_sec;
-               ts_wait.tv_nsec = (long) (1000 * tv_wait.tv_usec);
+               CDTIME_T_TO_TIMESPEC (wait_until - now, &ts_wait);
+               wait_until = wait_until + interval_g;
 
-               while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) == -1))
+               while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) != 0))
                {
                        if (errno != EINTR)
                        {
@@ -368,7 +365,6 @@ static int do_loop (void)
                }
        } /* while (loop == 0) */
 
-       DEBUG ("return (0);");
        return (0);
 } /* int do_loop */
 
index 93d356e..8dd0f42 100644 (file)
 # endif
 #endif
 
-extern char hostname_g[];
-extern int  interval_g;
-extern int  timeout_g;
+/* Type for time as used by "utils_time.h" */
+typedef uint64_t cdtime_t;
+
+extern char     hostname_g[];
+extern cdtime_t interval_g;
+extern int      timeout_g;
 
 #endif /* COLLECTD_H */
index 08653dc..87d7bf0 100644 (file)
@@ -833,7 +833,7 @@ int format_values (char *ret, size_t ret_len, /* {{{ */
                 offset += ((size_t) status); \
 } while (0)
 
-        BUFFER_ADD ("%lu", (unsigned long) vl->time);
+        BUFFER_ADD ("%.3f", CDTIME_T_TO_DOUBLE (vl->time));
 
         for (i = 0; i < ds->ds_num; i++)
         {
@@ -979,9 +979,22 @@ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds)
                if (i == -1)
                {
                        if (strcmp ("N", ptr) == 0)
-                               vl->time = time (NULL);
+                               vl->time = cdtime ();
                        else
-                               vl->time = (time_t) atoi (ptr);
+                       {
+                               char *endptr = NULL;
+                               double tmp;
+
+                               errno = 0;
+                               tmp = strtod (ptr, &endptr);
+                               if ((errno != 0)                    /* Overflow */
+                                               || (endptr == ptr)  /* Invalid string */
+                                               || (endptr == NULL) /* This should not happen */
+                                               || (*endptr != 0))  /* Trailing chars */
+                                       return (-1);
+
+                               vl->time = DOUBLE_TO_CDTIME_T (tmp);
+                       }
                }
                else
                {
index 99dded9..e162dd9 100644 (file)
@@ -1059,3 +1059,28 @@ int cf_util_get_port_number (const oconfig_item_t *ci) /* {{{ */
 
        return (service_name_to_port_number (ci->values[0].value.string));
 } /* }}} int cf_util_get_port_number */
+
+int cf_util_get_cdtime (const oconfig_item_t *ci, cdtime_t *ret_value) /* {{{ */
+{
+       if ((ci == NULL) || (ret_value == NULL))
+               return (EINVAL);
+
+       if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
+       {
+               ERROR ("cf_util_get_cdtime: The %s option requires "
+                               "exactly one numeric argument.", ci->key);
+               return (-1);
+       }
+
+       if (ci->values[0].value.number < 0.0)
+       {
+               ERROR ("cf_util_get_cdtime: The numeric argument of the %s "
+                               "option must not be negative.", ci->key);
+               return (-1);
+       }
+
+       *ret_value = DOUBLE_TO_CDTIME_T (ci->values[0].value.number);
+
+       return (0);
+} /* }}} int cf_util_get_cdtime */
+
index 519a6ff..65b1efc 100644 (file)
@@ -23,6 +23,7 @@
  **/
 
 #include "collectd.h"
+#include "utils_time.h"
 #include "liboconfig/oconfig.h"
 
 /*
@@ -113,4 +114,6 @@ int cf_util_get_flag (const oconfig_item_t *ci,
  * port number in the range [1-65535] or less than zero upon failure. */
 int cf_util_get_port_number (const oconfig_item_t *ci);
 
+int cf_util_get_cdtime (const oconfig_item_t *ci, cdtime_t *ret_value);
+
 #endif /* defined(CONFIGFILE_H) */
index 7aa6361..3dbe80e 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -163,7 +163,7 @@ static int init (void)
        DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors");
        INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s");
 
-       cpu_temp_retry_max = 86400 / interval_g;
+       cpu_temp_retry_max = 86400 / CDTIME_T_TO_TIME_T (interval_g);
 /* #endif PROCESSOR_CPU_LOAD_INFO */
 
 #elif defined(HAVE_LIBKSTAT)
index 46e2301..4b8aa72 100644 (file)
@@ -188,7 +188,7 @@ typedef struct {
        PluginData data;
        PyObject *values;    /* Sequence */
        PyObject *meta;      /* dict */
-       int interval;
+       double interval;
 } Values;
 PyTypeObject ValuesType;
 #define Values_New() PyObject_CallFunctionObjArgs((PyObject *) &ValuesType, (void *) 0)
index 96c1e3e..87a7b4e 100644 (file)
--- a/src/csv.c
+++ b/src/csv.c
@@ -53,7 +53,8 @@ static int value_list_to_string (char *buffer, int buffer_len,
 
        memset (buffer, '\0', buffer_len);
 
-       status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time);
+       status = ssnprintf (buffer, buffer_len, "%.3f",
+                       CDTIME_T_TO_DOUBLE (vl->time));
        if ((status < 1) || (status >= buffer_len))
                return (-1);
        offset = status;
@@ -298,8 +299,10 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl,
                }
 
                fprintf (use_stdio == 1 ? stdout : stderr,
-                        "PUTVAL %s interval=%i %s\n",
-                        filename, vl->interval, values);
+                        "PUTVAL %s interval=%.3f %s\n",
+                        filename,
+                        CDTIME_T_TO_DOUBLE (vl->interval),
+                        values);
                return (0);
        }
 
index cd9240a..caa41ef 100644 (file)
--- a/src/dbi.c
+++ b/src/dbi.c
@@ -566,7 +566,7 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
 
   udb_query_prepare_result (q, prep_area, hostname_g,
       /* plugin = */ "dbi", db->name,
-      column_names, column_num, /* interval = */ -1);
+      column_names, column_num, /* interval = */ 0);
 
   /* 0 = error; 1 = success; */
   status = dbi_result_first_row (res); /* {{{ */
index 6e63fe4..47da4e9 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -226,7 +226,7 @@ static void *dns_child_loop (void __attribute__((unused)) *dummy)
        pcap_obj = pcap_open_live ((pcap_device != NULL) ? pcap_device : "any",
                        PCAP_SNAPLEN,
                        0 /* Not promiscuous */,
-                       interval_g,
+                       (int) CDTIME_T_TO_MS (interval_g / 2),
                        pcap_error);
        if (pcap_obj == NULL)
        {
index 9aabe9f..8d5ae9c 100644 (file)
@@ -270,13 +270,14 @@ static void set_environment (void) /* {{{ */
   char buffer[1024];
 
 #ifdef HAVE_SETENV
-  ssnprintf (buffer, sizeof (buffer), "%i", interval_g);
+  ssnprintf (buffer, sizeof (buffer), "%.3f", CDTIME_T_TO_DOUBLE (interval_g));
   setenv ("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
 
   ssnprintf (buffer, sizeof (buffer), "%s", hostname_g);
   setenv ("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
 #else
-  ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%i", interval_g);
+  ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%.3f",
+      CDTIME_T_TO_DOUBLE (interval_g));
   putenv (buffer);
 
   ssnprintf (buffer, sizeof (buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
index 2ffc42a..8c774e5 100644 (file)
@@ -719,7 +719,7 @@ static int mc_handle_metadata_msg (Ganglia_metadata_msg *msg) /* {{{ */
           map->type, map->type_instance,
           ds->ds_num);
       if (se != NULL)
-        se->vl.interval = (int) msg_meta.metric.tmax;
+        se->vl.interval = TIME_T_TO_CDTIME_T (msg_meta.metric.tmax);
       pthread_mutex_unlock (&staging_lock);
 
       if (se == NULL)
index 95b3dbf..f341320 100644 (file)
@@ -136,7 +136,7 @@ static void sensor_read_handler (ipmi_sensor_t *sensor,
 
         if (c_ipmi_nofiy_notpresent)
         {
-          notification_t n = { NOTIF_WARNING, time(NULL), "", "", "ipmi",
+          notification_t n = { NOTIF_WARNING, cdtime (), "", "", "ipmi",
             "", "", "", NULL };
 
           sstrncpy (n.host, hostname_g, sizeof (n.host));
@@ -190,7 +190,7 @@ static void sensor_read_handler (ipmi_sensor_t *sensor,
 
     if (c_ipmi_nofiy_notpresent)
     {
-      notification_t n = { NOTIF_OKAY, time(NULL), "", "", "ipmi",
+      notification_t n = { NOTIF_OKAY, cdtime (), "", "", "ipmi",
         "", "", "", NULL };
 
       sstrncpy (n.host, hostname_g, sizeof (n.host));
@@ -363,7 +363,7 @@ static int sensor_list_add (ipmi_sensor_t *sensor)
 
   if (c_ipmi_nofiy_add && (c_ipmi_init_in_progress == 0))
   {
-    notification_t n = { NOTIF_OKAY, time(NULL), "", "", "ipmi",
+    notification_t n = { NOTIF_OKAY, cdtime (), "", "", "ipmi",
                          "", "", "", NULL };
 
     sstrncpy (n.host, hostname_g, sizeof (n.host));
@@ -417,7 +417,7 @@ static int sensor_list_remove (ipmi_sensor_t *sensor)
 
   if (c_ipmi_nofiy_remove && c_ipmi_active)
   {
-    notification_t n = { NOTIF_WARNING, time(NULL), "", "",
+    notification_t n = { NOTIF_WARNING, cdtime (), "", "",
                          "ipmi", "", "", "", NULL };
 
     sstrncpy (n.host, hostname_g, sizeof (n.host));
@@ -664,7 +664,8 @@ static int c_ipmi_init (void)
   int status;
 
   /* Don't send `ADD' notifications during startup (~ 1 minute) */
-  c_ipmi_init_in_progress = 1 + (60 / interval_g);
+  time_t iv = CDTIME_T_TO_TIME_T (interval_g);
+  c_ipmi_init_in_progress = 1 + (60 / iv);
 
   c_ipmi_active = 1;
 
index 87eee10..f3a583b 100644 (file)
@@ -235,8 +235,6 @@ static void cipvs_submit_connections (char *pi, char *ti, counter_t value)
        vl.values     = values;
        vl.values_len = 1;
 
-       vl.interval = interval_g;
-
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "ipvs", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, pi, sizeof (vl.plugin_instance));
@@ -260,8 +258,6 @@ static void cipvs_submit_if (char *pi, char *t, char *ti,
        vl.values     = values;
        vl.values_len = 2;
 
-       vl.interval = interval_g;
-
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "ipvs", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, pi, sizeof (vl.plugin_instance));
index 528ec9c..3089a53 100644 (file)
@@ -109,7 +109,7 @@ static int cjni_callback_register (JNIEnv *jvm_env, jobject o_name,
 static int cjni_read (user_data_t *user_data);
 static int cjni_write (const data_set_t *ds, const value_list_t *vl,
     user_data_t *ud);
-static int cjni_flush (int timeout, const char *identifier, user_data_t *ud);
+static int cjni_flush (cdtime_t timeout, const char *identifier, user_data_t *ud);
 static void cjni_log (int severity, const char *message, user_data_t *ud);
 static int cjni_notification (const notification_t *n, user_data_t *ud);
 
@@ -809,7 +809,7 @@ static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */
 #undef SET_STRING
 
   /* Set the `time' member. Java stores time in milliseconds. */
-  status = ctoj_long (jvm_env, ((jlong) vl->time) * ((jlong) 1000),
+  status = ctoj_long (jvm_env, (jlong) CDTIME_T_TO_MS (vl->time),
       c_valuelist, o_valuelist, "setTime");
   if (status != 0)
   {
@@ -819,7 +819,8 @@ static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */
   }
 
   /* Set the `interval' member.. */
-  status = ctoj_long (jvm_env, (jlong) vl->interval,
+  status = ctoj_long (jvm_env,
+      (jlong) CDTIME_T_TO_MS (vl->interval),
       c_valuelist, o_valuelist, "setInterval");
   if (status != 0)
   {
@@ -914,7 +915,7 @@ static jobject ctoj_notification (JNIEnv *jvm_env, /* {{{ */
     return (NULL);
   }
 
-  /* Set the `interval' member.. */
+  /* Set the `severity' member.. */
   status = ctoj_int (jvm_env, (jint) n->severity,
       c_notification, o_notification, "setSeverity");
   if (status != 0)
@@ -1242,7 +1243,7 @@ static int jtoc_value_list (JNIEnv *jvm_env, value_list_t *vl, /* {{{ */
     return (-1);
   }
   /* Java measures time in milliseconds. */
-  vl->time = (time_t) (tmp_long / ((jlong) 1000));
+  vl->time = MS_TO_CDTIME_T (tmp_long);
 
   status = jtoc_long (jvm_env, &tmp_long,
       class_ptr, object_ptr, "getInterval");
@@ -1251,7 +1252,7 @@ static int jtoc_value_list (JNIEnv *jvm_env, value_list_t *vl, /* {{{ */
     ERROR ("java plugin: jtoc_value_list: jtoc_long (getInterval) failed.");
     return (-1);
   }
-  vl->interval = (int) tmp_long;
+  vl->interval = MS_TO_CDTIME_T (tmp_long);
 
   status = jtoc_values_array (jvm_env, ds, vl, class_ptr, object_ptr);
   if (status != 0)
@@ -1729,7 +1730,7 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{
 
     case CB_TYPE_FLUSH:
       method_name = "flush";
-      method_signature = "(ILjava/lang/String;)I";
+      method_signature = "(Ljava/lang/Number;Ljava/lang/String;)I";
       break;
 
     case CB_TYPE_SHUTDOWN:
@@ -2551,11 +2552,12 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
 } /* }}} int cjni_write */
 
 /* Call the CB_TYPE_FLUSH callback pointed to by the `user_data_t' pointer. */
-static int cjni_flush (int timeout, const char *identifier, /* {{{ */
+static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
     user_data_t *ud)
 {
   JNIEnv *jvm_env;
   cjni_callback_info_t *cbi;
+  jobject o_timeout;
   jobject o_identifier;
   int status;
   int ret_status;
@@ -2578,21 +2580,32 @@ static int cjni_flush (int timeout, const char *identifier, /* {{{ */
 
   cbi = (cjni_callback_info_t *) ud->data;
 
+  o_timeout = ctoj_jdouble_to_number (jvm_env,
+      (jdouble) CDTIME_T_TO_DOUBLE (timeout));
+  if (o_timeout == NULL)
+  {
+    ERROR ("java plugin: cjni_flush: Converting double "
+        "to Number object failed.");
+    return (-1);
+  }
+
   o_identifier = NULL;
   if (identifier != NULL)
   {
     o_identifier = (*jvm_env)->NewStringUTF (jvm_env, identifier);
     if (o_identifier == NULL)
     {
+      (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
       ERROR ("java plugin: cjni_flush: NewStringUTF failed.");
       return (-1);
     }
   }
 
   ret_status = (*jvm_env)->CallIntMethod (jvm_env,
-      cbi->object, cbi->method, (jint) timeout, o_identifier);
+      cbi->object, cbi->method, o_timeout, o_identifier);
 
   (*jvm_env)->DeleteLocalRef (jvm_env, o_identifier);
+  (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
 
   status = cjni_thread_detach ();
   if (status != 0)
index 44f3832..5d9d84b 100644 (file)
@@ -125,17 +125,6 @@ static time_t last_refresh = (time_t) 0;
 
 static int refresh_lists (void);
 
-/* Submit functions. */
-static void cpu_submit (unsigned long long cpu_time,
-                        time_t t,
-                        virDomainPtr dom, const char *type);
-static void vcpu_submit (unsigned long long cpu_time,
-                         time_t t,
-                         virDomainPtr dom, int vcpu_nr, const char *type);
-static void submit_counter2 (const char *type, counter_t v0, counter_t v1,
-             time_t t,
-             virDomainPtr dom, const char *devname);
-
 /* ERROR(...) macro for virterrors. */
 #define VIRT_ERROR(conn,s) do {                 \
         virErrorPtr err;                        \
@@ -143,6 +132,113 @@ static void submit_counter2 (const char *type, counter_t v0, counter_t v1,
         if (err) ERROR ("%s: %s", (s), err->message);                   \
     } while(0)
 
+static void
+init_value_list (value_list_t *vl, virDomainPtr dom)
+{
+    int i, n;
+    const char *name;
+    char uuid[VIR_UUID_STRING_BUFLEN];
+    char  *host_ptr;
+    size_t host_len;
+
+    vl->interval = interval_g;
+
+    sstrncpy (vl->plugin, "libvirt", sizeof (vl->plugin));
+
+    vl->host[0] = '\0';
+    host_ptr = vl->host;
+    host_len = sizeof (vl->host);
+
+    /* Construct the hostname field according to HostnameFormat. */
+    for (i = 0; i < HF_MAX_FIELDS; ++i) {
+        if (hostname_format[i] == hf_none)
+            continue;
+
+        n = DATA_MAX_NAME_LEN - strlen (vl->host) - 2;
+
+        if (i > 0 && n >= 1) {
+            strncat (vl->host, ":", 1);
+            n--;
+        }
+
+        switch (hostname_format[i]) {
+        case hf_none: break;
+        case hf_hostname:
+            strncat (vl->host, hostname_g, n);
+            break;
+        case hf_name:
+            name = virDomainGetName (dom);
+            if (name)
+                strncat (vl->host, name, n);
+            break;
+        case hf_uuid:
+            if (virDomainGetUUIDString (dom, uuid) == 0)
+                strncat (vl->host, uuid, n);
+            break;
+        }
+    }
+
+    vl->host[sizeof (vl->host) - 1] = '\0';
+} /* void init_value_list */
+
+static void
+cpu_submit (unsigned long long cpu_time,
+            virDomainPtr dom, const char *type)
+{
+    value_t values[1];
+    value_list_t vl = VALUE_LIST_INIT;
+
+    init_value_list (&vl, dom);
+
+    values[0].counter = cpu_time;
+
+    vl.values = values;
+    vl.values_len = 1;
+
+    sstrncpy (vl.type, type, sizeof (vl.type));
+
+    plugin_dispatch_values (&vl);
+}
+
+static void
+vcpu_submit (counter_t cpu_time,
+             virDomainPtr dom, int vcpu_nr, const char *type)
+{
+    value_t values[1];
+    value_list_t vl = VALUE_LIST_INIT;
+
+    init_value_list (&vl, dom);
+
+    values[0].counter = cpu_time;
+    vl.values = values;
+    vl.values_len = 1;
+
+    sstrncpy (vl.type, type, sizeof (vl.type));
+    ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%d", vcpu_nr);
+
+    plugin_dispatch_values (&vl);
+}
+
+static void
+submit_counter2 (const char *type, counter_t v0, counter_t v1,
+             virDomainPtr dom, const char *devname)
+{
+    value_t values[2];
+    value_list_t vl = VALUE_LIST_INIT;
+
+    init_value_list (&vl, dom);
+
+    values[0].counter = v0;
+    values[1].counter = v1;
+    vl.values = values;
+    vl.values_len = 2;
+
+    sstrncpy (vl.type, type, sizeof (vl.type));
+    sstrncpy (vl.type_instance, devname, sizeof (vl.type_instance));
+
+    plugin_dispatch_values (&vl);
+} /* void submit_counter2 */
+
 static int
 lv_init (void)
 {
@@ -322,7 +418,7 @@ lv_read (void)
         if (virDomainGetInfo (domains[i], &info) != 0)
             continue;
 
-        cpu_submit (info.cpuTime, t, domains[i], "virt_cpu_total");
+        cpu_submit (info.cpuTime, domains[i], "virt_cpu_total");
 
         vinfo = malloc (info.nrVirtCpu * sizeof vinfo[0]);
         if (vinfo == NULL) {
@@ -338,7 +434,7 @@ lv_read (void)
 
         for (j = 0; j < info.nrVirtCpu; ++j)
             vcpu_submit (vinfo[j].cpuTime,
-                    t, domains[i], vinfo[j].number, "virt_vcpu");
+                    domains[i], vinfo[j].number, "virt_vcpu");
 
         sfree (vinfo);
     }
@@ -354,12 +450,12 @@ lv_read (void)
         if ((stats.rd_req != -1) && (stats.wr_req != -1))
             submit_counter2 ("disk_ops",
                     (counter_t) stats.rd_req, (counter_t) stats.wr_req,
-                    t, block_devices[i].dom, block_devices[i].path);
+                    block_devices[i].dom, block_devices[i].path);
 
         if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1))
             submit_counter2 ("disk_octets",
                     (counter_t) stats.rd_bytes, (counter_t) stats.wr_bytes,
-                    t, block_devices[i].dom, block_devices[i].path);
+                    block_devices[i].dom, block_devices[i].path);
     } /* for (nr_block_devices) */
 
     /* Get interface stats for each domain. */
@@ -378,22 +474,22 @@ lv_read (void)
        if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1))
            submit_counter2 ("if_octets",
                    (counter_t) stats.rx_bytes, (counter_t) stats.tx_bytes,
-                   t, interface_devices[i].dom, display_name);
+                   interface_devices[i].dom, display_name);
 
        if ((stats.rx_packets != -1) && (stats.tx_packets != -1))
            submit_counter2 ("if_packets",
                    (counter_t) stats.rx_packets, (counter_t) stats.tx_packets,
-                   t, interface_devices[i].dom, display_name);
+                   interface_devices[i].dom, display_name);
 
        if ((stats.rx_errs != -1) && (stats.tx_errs != -1))
            submit_counter2 ("if_errors",
                    (counter_t) stats.rx_errs, (counter_t) stats.tx_errs,
-                   t, interface_devices[i].dom, display_name);
+                   interface_devices[i].dom, display_name);
 
        if ((stats.rx_drop != -1) && (stats.tx_drop != -1))
            submit_counter2 ("if_dropped",
                    (counter_t) stats.rx_drop, (counter_t) stats.tx_drop,
-                   t, interface_devices[i].dom, display_name);
+                   interface_devices[i].dom, display_name);
     } /* for (nr_interface_devices) */
 
     return 0;
@@ -698,117 +794,6 @@ ignore_device_match (ignorelist_t *il, const char *domname, const char *devpath)
     return r;
 }
 
-static void
-init_value_list (value_list_t *vl, time_t t, virDomainPtr dom)
-{
-    int i, n;
-    const char *name;
-    char uuid[VIR_UUID_STRING_BUFLEN];
-    char  *host_ptr;
-    size_t host_len;
-
-    vl->time = t;
-    vl->interval = interval_g;
-
-    sstrncpy (vl->plugin, "libvirt", sizeof (vl->plugin));
-
-    vl->host[0] = '\0';
-    host_ptr = vl->host;
-    host_len = sizeof (vl->host);
-
-    /* Construct the hostname field according to HostnameFormat. */
-    for (i = 0; i < HF_MAX_FIELDS; ++i) {
-        if (hostname_format[i] == hf_none)
-            continue;
-
-        n = DATA_MAX_NAME_LEN - strlen (vl->host) - 2;
-
-        if (i > 0 && n >= 1) {
-            strncat (vl->host, ":", 1);
-            n--;
-        }
-
-        switch (hostname_format[i]) {
-        case hf_none: break;
-        case hf_hostname:
-            strncat (vl->host, hostname_g, n);
-            break;
-        case hf_name:
-            name = virDomainGetName (dom);
-            if (name)
-                strncat (vl->host, name, n);
-            break;
-        case hf_uuid:
-            if (virDomainGetUUIDString (dom, uuid) == 0)
-                strncat (vl->host, uuid, n);
-            break;
-        }
-    }
-
-    vl->host[sizeof (vl->host) - 1] = '\0';
-} /* void init_value_list */
-
-static void
-cpu_submit (unsigned long long cpu_time,
-            time_t t,
-            virDomainPtr dom, const char *type)
-{
-    value_t values[1];
-    value_list_t vl = VALUE_LIST_INIT;
-
-    init_value_list (&vl, t, dom);
-
-    values[0].counter = cpu_time;
-
-    vl.values = values;
-    vl.values_len = 1;
-
-    sstrncpy (vl.type, type, sizeof (vl.type));
-
-    plugin_dispatch_values (&vl);
-}
-
-static void
-vcpu_submit (counter_t cpu_time,
-             time_t t,
-             virDomainPtr dom, int vcpu_nr, const char *type)
-{
-    value_t values[1];
-    value_list_t vl = VALUE_LIST_INIT;
-
-    init_value_list (&vl, t, dom);
-
-    values[0].counter = cpu_time;
-    vl.values = values;
-    vl.values_len = 1;
-
-    sstrncpy (vl.type, type, sizeof (vl.type));
-    ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%d", vcpu_nr);
-
-    plugin_dispatch_values (&vl);
-}
-
-static void
-submit_counter2 (const char *type, counter_t v0, counter_t v1,
-             time_t t,
-             virDomainPtr dom, const char *devname)
-{
-    value_t values[2];
-    value_list_t vl = VALUE_LIST_INIT;
-
-    init_value_list (&vl, t, dom);
-
-    values[0].counter = v0;
-    values[1].counter = v1;
-    vl.values = values;
-    vl.values_len = 2;
-
-    sstrncpy (vl.type, type, sizeof (vl.type));
-    sstrncpy (vl.type_instance, devname, sizeof (vl.type_instance));
-
-    plugin_dispatch_values (&vl);
-} /* void submit_counter2 */
-
 static int
 lv_shutdown (void)
 {
index 6d0f6e0..60fb5d9 100644 (file)
@@ -92,7 +92,8 @@ static int logfile_config (const char *key, const char *value)
        return 0;
 } /* int logfile_config (const char *, const char *) */
 
-static void logfile_print (const char *msg, int severity, time_t timestamp_time)
+static void logfile_print (const char *msg, int severity,
+               cdtime_t timestamp_time)
 {
        FILE *fh;
        int do_close = 0;
@@ -126,7 +127,8 @@ static void logfile_print (const char *msg, int severity, time_t timestamp_time)
 
        if (print_timestamp)
        {
-               localtime_r (&timestamp_time, &timestamp_tm);
+               time_t tt = CDTIME_T_TO_TIME_T (timestamp_time);
+               localtime_r (&tt, &timestamp_tm);
 
                strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S",
                                &timestamp_tm);
@@ -179,7 +181,7 @@ static void logfile_log (int severity, const char *msg,
        if (severity > log_level)
                return;
 
-       logfile_print (msg, severity, time (NULL));
+       logfile_print (msg, severity, cdtime ());
 } /* void logfile_log (int, const char *) */
 
 static int logfile_notification (const notification_t *n,
@@ -218,7 +220,7 @@ static int logfile_notification (const notification_t *n,
        buf[sizeof (buf) - 1] = '\0';
 
        logfile_print (buf, LOG_INFO,
-                       (n->time > 0) ? n->time : time (NULL));
+                       (n->time != 0) ? n->time : cdtime ());
 
        return (0);
 } /* int logfile_notification */
index 4ac944a..2e27415 100644 (file)
@@ -34,29 +34,13 @@ struct mt_match_s;
 typedef struct mt_match_s mt_match_t;
 struct mt_match_s
 {
-  time_t future;
-  time_t past;
+  cdtime_t future;
+  cdtime_t past;
 };
 
 /*
  * internal helper functions
  */
-static int mt_config_add_time_t (time_t *ret_value, /* {{{ */
-    oconfig_item_t *ci)
-{
-
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
-  {
-    ERROR ("timediff match: `%s' needs exactly one numeric argument.",
-        ci->key);
-    return (-1);
-  }
-
-  *ret_value = (time_t) ci->values[0].value.number;
-
-  return (0);
-} /* }}} int mt_config_add_time_t */
-
 static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   mt_match_t *m;
@@ -80,9 +64,9 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
     oconfig_item_t *child = ci->children + i;
 
     if (strcasecmp ("Future", child->key) == 0)
-      status = mt_config_add_time_t (&m->future, child);
+      status = cf_util_get_cdtime (child, &m->future);
     else if (strcasecmp ("Past", child->key) == 0)
-      status = mt_config_add_time_t (&m->past, child);
+      status = cf_util_get_cdtime (child, &m->past);
     else
     {
       ERROR ("timediff match: The `%s' configuration option is not "
@@ -132,13 +116,13 @@ static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */
     notification_meta_t __attribute__((unused)) **meta, void **user_data)
 {
   mt_match_t *m;
-  time_t now;
+  cdtime_t now;
 
   if ((user_data == NULL) || (*user_data == NULL))
     return (-1);
 
   m = *user_data;
-  now = time (NULL);
+  now = cdtime ();
 
   if (m->future != 0)
   {
index 8490bf6..8b4a8fc 100644 (file)
@@ -176,12 +176,14 @@ static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */
                p.events = POLLIN | POLLERR | POLLHUP;
                p.revents = 0;
 
-               status = poll (&p, /* nfds = */ 1, /* timeout = */ 1000 * interval_g);
+               status = poll (&p, /* nfds = */ 1,
+                               /* timeout = */ CDTIME_T_TO_MS (interval_g));
                if (status <= 0)
                {
                        if (status == 0)
                        {
-                               ERROR ("memcached: poll(2) timed out after %i seconds.", interval_g);
+                               ERROR ("memcached: poll(2) timed out after %.3f seconds.",
+                                               CDTIME_T_TO_DOUBLE (interval_g));
                        }
                        else
                        {
index adab0d0..3824097 100644 (file)
@@ -94,7 +94,7 @@ struct mb_host_s /* {{{ */
   char node[NI_MAXHOST];
   /* char service[NI_MAXSERV]; */
   int port;
-  int interval;
+  cdtime_t interval;
 
   mb_slave_t *slaves;
   size_t slaves_num;
@@ -771,7 +771,7 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
         status = -1;
     }
     else if (strcasecmp ("Interval", child->key) == 0)
-      status = cf_util_get_int (child, &host->interval);
+      status = cf_util_get_cdtime (child, &host->interval);
     else if (strcasecmp ("Slave", child->key) == 0)
       /* Don't set status: Gracefully continue if a slave fails. */
       mb_config_add_slave (host, child);
@@ -797,21 +797,19 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
   {
     user_data_t ud;
     char name[1024];
-    struct timespec interval;
+    struct timespec interval = { 0, 0 };
 
     ud.data = host;
     ud.free_func = host_free;
 
     ssnprintf (name, sizeof (name), "modbus-%s", host->host);
 
-    interval.tv_nsec = 0;
-    if (host->interval > 0)
-      interval.tv_sec = host->interval;
-    else
-      interval.tv_sec = 0;
+    CDTIME_T_TO_TIMESPEC (host->interval, &interval);
 
     plugin_register_complex_read (/* group = */ NULL, name,
-        mb_read, (interval.tv_sec > 0) ? &interval : NULL, &ud);
+        /* callback = */ mb_read,
+        /* interval = */ (host->interval > 0) ? &interval : NULL,
+        &ud);
   }
   else
   {
index a01bbe4..1ca3b48 100644 (file)
@@ -485,7 +485,7 @@ static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con)
 
        if (db->slave_notif)
        {
-               notification_t n = { 0, time (NULL), "", "",
+               notification_t n = { 0, cdtime (), "", "",
                        "mysql", "", "time_offset", "", NULL };
 
                char *io, *sql;
index c50b3db..5c4b6e7 100644 (file)
@@ -38,8 +38,8 @@ typedef void service_handler_t(host_config_t *host, na_elem_t *result, void *dat
 
 struct cna_interval_s
 {
-       time_t interval;
-       time_t last_read;
+       cdtime_t interval;
+       cdtime_t last_read;
 };
 typedef struct cna_interval_s cna_interval_t;
 
@@ -79,7 +79,7 @@ typedef struct {
        cna_interval_t interval;
        na_elem_t *query;
 
-       time_t timestamp;
+       cdtime_t timestamp;
        uint64_t name_cache_hit;
        uint64_t name_cache_miss;
        uint64_t find_dir_hit;
@@ -104,7 +104,7 @@ typedef struct {
 typedef struct disk_s {
        char *name;
        uint32_t flags;
-       time_t timestamp;
+       cdtime_t timestamp;
        uint64_t disk_busy;
        uint64_t base_for_disk_busy;
        double disk_busy_percent;
@@ -153,7 +153,7 @@ typedef struct data_volume_perf_s data_volume_perf_t;
 struct data_volume_perf_s {
        char *name;
        uint32_t flags;
-       time_t timestamp;
+       cdtime_t timestamp;
 
        uint64_t read_bytes;
        uint64_t write_bytes;
@@ -242,7 +242,7 @@ struct host_config_s {
        int port;
        char *username;
        char *password;
-       int interval;
+       cdtime_t interval;
 
        na_server_t *srv;
        cfg_wafl_t *cfg_wafl;
@@ -566,7 +566,7 @@ static int submit_values (const char *host, /* {{{ */
                const char *plugin_inst,
                const char *type, const char *type_inst,
                value_t *values, int values_len,
-               time_t timestamp, int interval)
+               cdtime_t timestamp, cdtime_t interval)
 {
        value_list_t vl = VALUE_LIST_INIT;
 
@@ -595,7 +595,7 @@ static int submit_values (const char *host, /* {{{ */
 
 static int submit_two_counters (const char *host, const char *plugin_inst, /* {{{ */
                const char *type, const char *type_inst, counter_t val0, counter_t val1,
-               time_t timestamp, int interval)
+               cdtime_t timestamp, cdtime_t interval)
 {
        value_t values[2];
 
@@ -607,7 +607,8 @@ static int submit_two_counters (const char *host, const char *plugin_inst, /* {{
 } /* }}} int submit_two_counters */
 
 static int submit_counter (const char *host, const char *plugin_inst, /* {{{ */
-               const char *type, const char *type_inst, counter_t counter, time_t timestamp, int interval)
+               const char *type, const char *type_inst, counter_t counter,
+               cdtime_t timestamp, cdtime_t interval)
 {
        value_t v;
 
@@ -619,7 +620,7 @@ static int submit_counter (const char *host, const char *plugin_inst, /* {{{ */
 
 static int submit_two_gauge (const char *host, const char *plugin_inst, /* {{{ */
                const char *type, const char *type_inst, gauge_t val0, gauge_t val1,
-               time_t timestamp, int interval)
+               cdtime_t timestamp, cdtime_t interval)
 {
        value_t values[2];
 
@@ -631,7 +632,8 @@ static int submit_two_gauge (const char *host, const char *plugin_inst, /* {{{ *
 } /* }}} int submit_two_gauge */
 
 static int submit_double (const char *host, const char *plugin_inst, /* {{{ */
-               const char *type, const char *type_inst, double d, time_t timestamp, int interval)
+               const char *type, const char *type_inst, double d,
+               cdtime_t timestamp, cdtime_t interval)
 {
        value_t v;
 
@@ -650,8 +652,8 @@ static int submit_cache_ratio (const char *host, /* {{{ */
                uint64_t new_misses,
                uint64_t old_hits,
                uint64_t old_misses,
-               time_t timestamp,
-               int interval)
+               cdtime_t timestamp,
+               cdtime_t interval)
 {
        value_t v;
 
@@ -816,6 +818,16 @@ static int submit_volume_perf_data (const char *hostname, /* {{{ */
        return (0);
 } /* }}} int submit_volume_perf_data */
 
+static cdtime_t cna_child_get_cdtime (na_elem_t *data) /* {{{ */
+{
+       time_t t;
+
+       t = (time_t) na_child_get_uint64 (data, "timestamp", /* default = */ 0);
+
+       return (TIME_T_TO_CDTIME_T (t));
+} /* }}} cdtime_t cna_child_get_cdtime */
+
+
 /* 
  * Query functions
  *
@@ -835,7 +847,7 @@ static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /*
 
        memset (&perf_data, 0, sizeof (perf_data));
        
-       perf_data.timestamp = (time_t) na_child_get_uint64 (data, "timestamp", 0);
+       perf_data.timestamp = cna_child_get_cdtime (data);
 
        instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
        if (instances == NULL)
@@ -950,7 +962,7 @@ static int cna_query_wafl (host_config_t *host) /* {{{ */
 {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
 
        if (host == NULL)
                return (EINVAL);
@@ -959,7 +971,7 @@ static int cna_query_wafl (host_config_t *host) /* {{{ */
        if (host->cfg_wafl == NULL)
                return (0);
 
-       now = time (NULL);
+       now = cdtime ();
        if ((host->cfg_wafl->interval.interval + host->cfg_wafl->interval.last_read) > now)
                return (0);
 
@@ -988,9 +1000,9 @@ static int cna_query_wafl (host_config_t *host) /* {{{ */
 
 /* Data corresponding to <Disks /> */
 static int cna_handle_disk_data (const char *hostname, /* {{{ */
-               cfg_disk_t *cfg_disk, na_elem_t *data, int interval)
+               cfg_disk_t *cfg_disk, na_elem_t *data, cdtime_t interval)
 {
-       time_t timestamp;
+       cdtime_t timestamp;
        na_elem_t *instances;
        na_elem_t *instance;
        na_elem_iter_t instance_iter;
@@ -999,7 +1011,7 @@ static int cna_handle_disk_data (const char *hostname, /* {{{ */
        if ((cfg_disk == NULL) || (data == NULL))
                return (EINVAL);
        
-       timestamp = (time_t) na_child_get_uint64(data, "timestamp", 0);
+       timestamp = cna_child_get_cdtime (data);
 
        instances = na_elem_child (data, "instances");
        if (instances == NULL)
@@ -1144,7 +1156,7 @@ static int cna_query_disk (host_config_t *host) /* {{{ */
 {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
 
        if (host == NULL)
                return (EINVAL);
@@ -1154,7 +1166,7 @@ static int cna_query_disk (host_config_t *host) /* {{{ */
        if (host->cfg_disk == NULL)
                return (0);
 
-       now = time (NULL);
+       now = cdtime ();
        if ((host->cfg_disk->interval.interval + host->cfg_disk->interval.last_read) > now)
                return (0);
 
@@ -1183,14 +1195,14 @@ static int cna_query_disk (host_config_t *host) /* {{{ */
 
 /* Data corresponding to <VolumePerf /> */
 static int cna_handle_volume_perf_data (const char *hostname, /* {{{ */
-               cfg_volume_perf_t *cvp, na_elem_t *data, int interval)
+               cfg_volume_perf_t *cvp, na_elem_t *data, cdtime_t interval)
 {
-       time_t timestamp;
+       cdtime_t timestamp;
        na_elem_t *elem_instances;
        na_elem_iter_t iter_instances;
        na_elem_t *elem_instance;
        
-       timestamp = (time_t) na_child_get_uint64(data, "timestamp", 0);
+       timestamp = cna_child_get_cdtime (data);
 
        elem_instances = na_elem_child(data, "instances");
        if (elem_instances == NULL)
@@ -1315,7 +1327,7 @@ static int cna_query_volume_perf (host_config_t *host) /* {{{ */
 {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
 
        if (host == NULL)
                return (EINVAL);
@@ -1325,7 +1337,7 @@ static int cna_query_volume_perf (host_config_t *host) /* {{{ */
        if (host->cfg_volume_perf == NULL)
                return (0);
 
-       now = time (NULL);
+       now = cdtime ();
        if ((host->cfg_volume_perf->interval.interval + host->cfg_volume_perf->interval.last_read) > now)
                return (0);
 
@@ -1444,7 +1456,7 @@ static int cna_change_volume_status (const char *hostname, /* {{{ */
        notification_t n;
 
        memset (&n, 0, sizeof (&n));
-       n.time = time (NULL);
+       n.time = cdtime ();
        sstrncpy (n.host, hostname, sizeof (n.host));
        sstrncpy (n.plugin, "netapp", sizeof (n.plugin));
        sstrncpy (n.plugin_instance, v->name, sizeof (n.plugin_instance));
@@ -1679,7 +1691,7 @@ static int cna_query_volume_usage (host_config_t *host) /* {{{ */
 {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
 
        if (host == NULL)
                return (EINVAL);
@@ -1689,7 +1701,7 @@ static int cna_query_volume_usage (host_config_t *host) /* {{{ */
        if (host->cfg_volume_usage == NULL)
                return (0);
 
-       now = time (NULL);
+       now = cdtime ();
        if ((host->cfg_volume_usage->interval.interval + host->cfg_volume_usage->interval.last_read) > now)
                return (0);
 
@@ -1730,9 +1742,9 @@ static int cna_handle_system_data (const char *hostname, /* {{{ */
        uint32_t counter_flags = 0;
 
        const char *instance;
-       time_t timestamp;
+       cdtime_t timestamp;
        
-       timestamp = (time_t) na_child_get_uint64 (data, "timestamp", 0);
+       timestamp = cna_child_get_cdtime (data);
 
        instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
        if (instances == NULL)
@@ -1839,7 +1851,7 @@ static int cna_query_system (host_config_t *host) /* {{{ */
 {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
 
        if (host == NULL)
                return (EINVAL);
@@ -1848,7 +1860,7 @@ static int cna_query_system (host_config_t *host) /* {{{ */
        if (host->cfg_system == NULL)
                return (0);
 
-       now = time (NULL);
+       now = cdtime ();
        if ((host->cfg_system->interval.interval + host->cfg_system->interval.last_read) > now)
                return (0);
 
@@ -1905,23 +1917,12 @@ static int cna_config_bool_to_flag (const oconfig_item_t *ci, /* {{{ */
 static int cna_config_get_interval (const oconfig_item_t *ci, /* {{{ */
                cna_interval_t *out_interval)
 {
-       time_t tmp;
-
-       if ((ci == NULL) || (out_interval == NULL))
-               return (EINVAL);
-
-       if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
-       {
-               WARNING ("netapp plugin: The `Interval' option needs exactly one numeric argument.");
-               return (-1);
-       }
+       cdtime_t tmp = 0;
+       int status;
 
-       tmp = (time_t) (ci->values[0].value.number + .5);
-       if (tmp < 1)
-       {
-               WARNING ("netapp plugin: The `Interval' option needs a positive integer argument.");
-               return (-1);
-       }
+       status = cf_util_get_cdtime (ci, &tmp);
+       if (status != 0)
+               return (status);
 
        out_interval->interval = tmp;
        out_interval->last_read = 0;
@@ -2421,11 +2422,7 @@ static host_config_t *cna_config_host (const oconfig_item_t *ci) /* {{{ */
                } else if (!strcasecmp(item->key, "Password")) {
                        status = cf_util_get_string (item, &host->password);
                } else if (!strcasecmp(item->key, "Interval")) {
-                       if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_NUMBER || item->values[0].value.number != (int) item->values[0].value.number || item->values[0].value.number < 2) {
-                               WARNING("netapp plugin: \"Interval\" of host %s needs exactly one integer argument.", ci->values[0].value.string);
-                               continue;
-                       }
-                       host->interval = item->values[0].value.number;
+                       status = cf_util_get_cdtime (item, &host->interval);
                } else if (!strcasecmp(item->key, "WAFL")) {
                        cna_config_wafl(host, item);
                } else if (!strcasecmp(item->key, "Disks")) {
@@ -2556,8 +2553,7 @@ static int cna_config (oconfig_item_t *ci) { /* {{{ */
 
                        ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
 
-                       memset (&interval, 0, sizeof (interval));
-                       interval.tv_sec = host->interval;
+                       CDTIME_T_TO_TIMESPEC (host->interval, &interval);
 
                        memset (&ud, 0, sizeof (ud));
                        ud.data = host;
index 3ad1177..7a1fcf7 100644 (file)
@@ -1381,8 +1381,19 @@ static int parse_packet (sockent_t *se, /* {{{ */
                                        &tmp);
                        if (status == 0)
                        {
-                               vl.time = (time_t) tmp;
-                               n.time = (time_t) tmp;
+                               vl.time = TIME_T_TO_CDTIME_T (tmp);
+                               n.time  = TIME_T_TO_CDTIME_T (tmp);
+                       }
+               }
+               else if (pkg_type == TYPE_TIME_HR)
+               {
+                       uint64_t tmp = 0;
+                       status = parse_part_number (&buffer, &buffer_size,
+                                       &tmp);
+                       if (status == 0)
+                       {
+                               vl.time = (cdtime_t) tmp;
+                               n.time  = (cdtime_t) tmp;
                        }
                }
                else if (pkg_type == TYPE_INTERVAL)
@@ -1391,7 +1402,15 @@ static int parse_packet (sockent_t *se, /* {{{ */
                        status = parse_part_number (&buffer, &buffer_size,
                                        &tmp);
                        if (status == 0)
-                               vl.interval = (int) tmp;
+                               vl.interval = TIME_T_TO_CDTIME_T (tmp);
+               }
+               else if (pkg_type == TYPE_INTERVAL_HR)
+               {
+                       uint64_t tmp = 0;
+                       status = parse_part_number (&buffer, &buffer_size,
+                                       &tmp);
+                       if (status == 0)
+                               vl.interval = (cdtime_t) tmp;
                }
                else if (pkg_type == TYPE_HOST)
                {
@@ -2587,7 +2606,7 @@ static int add_to_buffer (char *buffer, int buffer_size, /* {{{ */
 
        if (vl_def->time != vl->time)
        {
-               if (write_part_number (&buffer, &buffer_size, TYPE_TIME,
+               if (write_part_number (&buffer, &buffer_size, TYPE_TIME_HR,
                                        (uint64_t) vl->time))
                        return (-1);
                vl_def->time = vl->time;
@@ -2595,7 +2614,7 @@ static int add_to_buffer (char *buffer, int buffer_size, /* {{{ */
 
        if (vl_def->interval != vl->interval)
        {
-               if (write_part_number (&buffer, &buffer_size, TYPE_INTERVAL,
+               if (write_part_number (&buffer, &buffer_size, TYPE_INTERVAL_HR,
                                        (uint64_t) vl->interval))
                        return (-1);
                vl_def->interval = vl->interval;
@@ -3077,8 +3096,7 @@ static int network_notification (const notification_t *n,
 
   memset (buffer, '\0', sizeof (buffer));
 
-
-  status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME,
+  status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME_HR,
       (uint64_t) n->time);
   if (status != 0)
     return (-1);
@@ -3352,9 +3370,9 @@ static int network_init (void)
  * just send the buffer if `flush'  is called - if the requested value was in
  * there, good. If not, well, then there is nothing to flush.. -octo
  */
-static int network_flush (int timeout,
-               const char __attribute__((unused)) *identifier,
-               user_data_t __attribute__((unused)) *user_data)
+static int network_flush (__attribute__((unused)) cdtime_t timeout,
+               __attribute__((unused)) const char *identifier,
+               __attribute__((unused)) user_data_t *user_data)
 {
        pthread_mutex_lock (&send_buffer_lock);
 
index 777616c..1b35456 100644 (file)
 
 #define TYPE_HOST            0x0000
 #define TYPE_TIME            0x0001
+#define TYPE_TIME_HR         0x0008
 #define TYPE_PLUGIN          0x0002
 #define TYPE_PLUGIN_INSTANCE 0x0003
 #define TYPE_TYPE            0x0004
 #define TYPE_TYPE_INSTANCE   0x0005
 #define TYPE_VALUES          0x0006
 #define TYPE_INTERVAL        0x0007
+#define TYPE_INTERVAL_HR     0x0009
 
 /* Types to transmit notifications */
 #define TYPE_MESSAGE         0x0100
index 0aed27f..da6894a 100644 (file)
@@ -230,6 +230,7 @@ static int notify_email_notification (const notification_t *n,
 {
   smtp_recipient_t recipient;
 
+  time_t tt;
   struct tm timestamp_tm;
   char timestamp_str[64];
 
@@ -249,7 +250,8 @@ static int notify_email_notification (const notification_t *n,
       (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject,
       severity, n->host);
 
-  localtime_r (&n->time, &timestamp_tm);
+  tt = CDTIME_T_TO_TIME_T (n->time);
+  localtime_r (&tt, &timestamp_tm);
   strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S",
       &timestamp_tm);
   timestamp_str[sizeof (timestamp_str) - 1] = '\0';
index 462458c..09a6bf0 100644 (file)
@@ -59,7 +59,7 @@ static ow_family_features_t ow_family_features[] =
 static int ow_family_features_num = STATIC_ARRAY_SIZE (ow_family_features);
 
 static char *device_g = NULL;
-static int   ow_interval = 0;
+static cdtime_t ow_interval = 0;
 
 static const char *config_keys[] =
 {
@@ -106,10 +106,10 @@ static int cow_load_config (const char *key, const char *value)
   }
   else if (strcasecmp ("Interval", key) == 0)
   {
-    int tmp;
-    tmp = atoi (value);
-    if (tmp > 0)
-      ow_interval = tmp;
+    double tmp;
+    tmp = atof (value);
+    if (tmp > 0.0)
+      ow_interval = DOUBLE_TO_CDTIME_T (tmp);
     else
       ERROR ("onewire plugin: Invalid `Interval' setting: %s", value);
   }
@@ -306,12 +306,11 @@ static int cow_init (void)
     return (1);
   }
 
-  memset (&cb_interval, 0, sizeof (cb_interval));
-  if (ow_interval > 0)
-    cb_interval.tv_sec = (time_t) ow_interval;
+  CDTIME_T_TO_TIMESPEC (ow_interval, &cb_interval);
 
   plugin_register_complex_read (/* group = */ NULL, "onewire", cow_read,
-      &cb_interval, /* user data = */ NULL);
+      (ow_interval != 0) ? &cb_interval : NULL,
+      /* user data = */ NULL);
   plugin_register_shutdown ("onewire", cow_shutdown);
 
   return (0);
index 2f21851..0356749 100644 (file)
@@ -586,7 +586,7 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
 
   status = udb_query_prepare_result (q, prep_area, hostname_g,
       /* plugin = */ "oracle", db->name, column_names, column_num,
-      /* interval = */ -1);
+      /* interval = */ 0);
   if (status != 0)
   {
     ERROR ("oracle plugin: o_read_database_query (%s, %s): "
index 7260580..f8a4822 100644 (file)
@@ -235,15 +235,6 @@ struct {
        { "", NULL }
 };
 
-struct {
-       char  name[64];
-       int  *var;
-} g_integers[] =
-{
-       { "Collectd::interval_g", &interval_g },
-       { "", NULL }
-};
-
 /*
  * Helper functions for data type conversion.
  */
@@ -397,10 +388,16 @@ static int hv2value_list (pTHX_ HV *hash, value_list_t *vl)
        }
 
        if (NULL != (tmp = hv_fetch (hash, "time", 4, 0)))
-               vl->time = (time_t)SvIV (*tmp);
+       {
+               double t = SvNV (*tmp);
+               vl->time = DOUBLE_TO_CDTIME_T (t);
+       }
 
        if (NULL != (tmp = hv_fetch (hash, "interval", 8, 0)))
-               vl->interval = SvIV (*tmp);
+       {
+               double t = SvNV (*tmp);
+               vl->interval = DOUBLE_TO_CDTIME_T (t);
+       }
 
        if (NULL != (tmp = hv_fetch (hash, "host", 4, 0)))
                sstrncpy (vl->host, SvPV_nolen (*tmp), sizeof (vl->host));
@@ -552,9 +549,12 @@ static int hv2notification (pTHX_ HV *hash, notification_t *n)
                n->severity = NOTIF_FAILURE;
 
        if (NULL != (tmp = hv_fetch (hash, "time", 4, 0)))
-               n->time = (time_t)SvIV (*tmp);
+       {
+               double t = SvNV (*tmp);
+               n->time = DOUBLE_TO_CDTIME_T (t);
+       }
        else
-               n->time = time (NULL);
+               n->time = cdtime ();
 
        if (NULL != (tmp = hv_fetch (hash, "message", 7, 0)))
                sstrncpy (n->message, SvPV_nolen (*tmp), sizeof (n->message));
@@ -672,11 +672,17 @@ static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash)
                return -1;
 
        if (0 != vl->time)
-               if (NULL == hv_store (hash, "time", 4, newSViv (vl->time), 0))
+       {
+               double t = CDTIME_T_TO_DOUBLE (vl->time);
+               if (NULL == hv_store (hash, "time", 4, newSVnv (t), 0))
                        return -1;
+       }
 
-       if (NULL == hv_store (hash, "interval", 8, newSViv (vl->interval), 0))
-               return -1;
+       {
+               double t = CDTIME_T_TO_DOUBLE (vl->interval);
+               if (NULL == hv_store (hash, "interval", 8, newSVnv (t), 0))
+                       return -1;
+       }
 
        if ('\0' != vl->host[0])
                if (NULL == hv_store (hash, "host", 4, newSVpv (vl->host, 0), 0))
@@ -754,8 +760,11 @@ static int notification2hv (pTHX_ notification_t *n, HV *hash)
                return -1;
 
        if (0 != n->time)
-               if (NULL == hv_store (hash, "time", 4, newSViv (n->time), 0))
+       {
+               double t = CDTIME_T_TO_DOUBLE (n->time);
+               if (NULL == hv_store (hash, "time", 4, newSVnv (t), 0))
                        return -1;
+       }
 
        if ('\0' != *n->message)
                if (NULL == hv_store (hash, "message", 7, newSVpv (n->message, 0), 0))
@@ -1106,11 +1115,15 @@ static int pplugin_call_all (pTHX_ int type, ...)
                XPUSHs (sv_2mortal (newRV_noinc ((SV *)notif)));
        }
        else if (PLUGIN_FLUSH == type) {
+               cdtime_t timeout;
+
                /*
                 * $_[0] = $timeout;
                 * $_[1] = $identifier;
                 */
-               XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
+               timeout = va_arg (ap, cdtime_t);
+
+               XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
                XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
        }
 
@@ -1986,7 +1999,7 @@ static int perl_notify (const notification_t *notif,
        return pplugin_call_all (aTHX_ PLUGIN_NOTIF, notif);
 } /* static int perl_notify (const notification_t *) */
 
-static int perl_flush (int timeout, const char *identifier,
+static int perl_flush (cdtime_t timeout, const char *identifier,
                user_data_t __attribute__((unused)) *user_data)
 {
        dTHX;
@@ -2088,19 +2101,27 @@ static int g_pv_set (pTHX_ SV *var, MAGIC *mg)
        return 0;
 } /* static int g_pv_set (pTHX_ SV *, MAGIC *) */
 
-static int g_iv_get (pTHX_ SV *var, MAGIC *mg)
+static int g_interval_get (pTHX_ SV *var, MAGIC *mg)
 {
-       int *iv = (int *)mg->mg_ptr;
-       sv_setiv (var, *iv);
+       cdtime_t *interval = (cdtime_t *)mg->mg_ptr;
+       double nv;
+
+       nv = CDTIME_T_TO_DOUBLE (*interval);
+
+       sv_setnv (var, nv);
        return 0;
-} /* static int g_iv_get (pTHX_ SV *, MAGIC *) */
+} /* static int g_interval_get (pTHX_ SV *, MAGIC *) */
 
-static int g_iv_set (pTHX_ SV *var, MAGIC *mg)
+static int g_interval_set (pTHX_ SV *var, MAGIC *mg)
 {
-       int *iv = (int *)mg->mg_ptr;
-       *iv = (int)SvIV (var);
+       cdtime_t *interval = (cdtime_t *)mg->mg_ptr;
+       double nv;
+
+       nv = (double)SvNV (var);
+
+       *interval = DOUBLE_TO_CDTIME_T (nv);
        return 0;
-} /* static int g_iv_set (pTHX_ SV *, MAGIC *) */
+} /* static int g_interval_set (pTHX_ SV *, MAGIC *) */
 
 static MGVTBL g_pv_vtbl = {
        g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL
@@ -2108,8 +2129,8 @@ static MGVTBL g_pv_vtbl = {
                , NULL
 #endif
 };
-static MGVTBL g_iv_vtbl = {
-       g_iv_get, g_iv_set, NULL, NULL, NULL, NULL, NULL
+static MGVTBL g_interval_vtbl = {
+       g_interval_get, g_interval_set, NULL, NULL, NULL, NULL, NULL
 #if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL
                , NULL
 #endif
@@ -2151,12 +2172,11 @@ static void xs_init (pTHX)
                                g_strings[i].var, 0);
        }
 
-       /* global integers */
-       for (i = 0; '\0' != g_integers[i].name[0]; ++i) {
-               tmp = get_sv (g_integers[i].name, 1);
-               sv_magicext (tmp, NULL, PERL_MAGIC_ext, &g_iv_vtbl,
-                               (char *)g_integers[i].var, 0);
-       }
+       tmp = get_sv ("Collectd::interval_g", /* create = */ 1);
+       sv_magicext (tmp, NULL, /* how = */ PERL_MAGIC_ext,
+                       /* vtbl = */ &g_interval_vtbl,
+                       /* name = */ (char *) &interval_g, /* namelen = */ 0);
+
        return;
 } /* static void xs_init (pTHX) */
 
index 65d3875..f6bc506 100644 (file)
@@ -336,7 +336,7 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
        while (read_loop != 0)
        {
                read_func_t *rf;
-               struct timeval now;
+               cdtime_t now;
                int status;
                int rf_type;
                int rc;
@@ -347,10 +347,9 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
                {
                        struct timespec abstime;
 
-                       gettimeofday (&now, /* timezone = */ NULL);
+                       now = cdtime ();
 
-                       abstime.tv_sec = now.tv_sec + interval_g;
-                       abstime.tv_nsec = 1000 * now.tv_usec;
+                       CDTIME_T_TO_TIMESPEC (now + interval_g, &abstime);
 
                        pthread_mutex_lock (&read_lock);
                        pthread_cond_timedwait (&read_cond, &read_lock,
@@ -361,15 +360,13 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
 
                if ((rf->rf_interval.tv_sec == 0) && (rf->rf_interval.tv_nsec == 0))
                {
-                       gettimeofday (&now, /* timezone = */ NULL);
+                       now = cdtime ();
 
-                       rf->rf_interval.tv_sec = interval_g;
-                       rf->rf_interval.tv_nsec = 0;
+                       CDTIME_T_TO_TIMESPEC (interval_g, &rf->rf_interval);
 
                        rf->rf_effective_interval = rf->rf_interval;
 
-                       rf->rf_next_read.tv_sec = now.tv_sec;
-                       rf->rf_next_read.tv_nsec = 1000 * now.tv_usec;
+                       CDTIME_T_TO_TIMESPEC (now, &rf->rf_next_read);
                }
 
                /* sleep until this entry is due,
@@ -459,7 +456,7 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
                }
 
                /* update the ``next read due'' field */
-               gettimeofday (&now, /* timezone = */ NULL);
+               now = cdtime ();
 
                DEBUG ("plugin_read_thread: Effective interval of the "
                                "%s plugin is %i.%09i.",
@@ -476,15 +473,12 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
                NORMALIZE_TIMESPEC (rf->rf_next_read);
 
                /* Check, if `rf_next_read' is in the past. */
-               if ((rf->rf_next_read.tv_sec < now.tv_sec)
-                               || ((rf->rf_next_read.tv_sec == now.tv_sec)
-                                       && (rf->rf_next_read.tv_nsec < (1000 * now.tv_usec))))
+               if (TIMESPEC_TO_CDTIME_T (&rf->rf_next_read) < now)
                {
                        /* `rf_next_read' is in the past. Insert `now'
                         * so this value doesn't trail off into the
                         * past too much. */
-                       rf->rf_next_read.tv_sec = now.tv_sec;
-                       rf->rf_next_read.tv_nsec = 1000 * now.tv_usec;
+                       CDTIME_T_TO_TIMESPEC (now, &rf->rf_next_read);
                }
 
                DEBUG ("plugin_read_thread: Next read of the %s plugin at %i.%09i.",
@@ -1251,7 +1245,7 @@ int plugin_write (const char *plugin, /* {{{ */
   return (status);
 } /* }}} int plugin_write */
 
-int plugin_flush (const char *plugin, int timeout, const char *identifier)
+int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier)
 {
   llentry_t *le;
 
@@ -1296,7 +1290,8 @@ void plugin_shutdown_all (void)
 
        destroy_read_heap ();
 
-       plugin_flush (/* plugin = */ NULL, /* timeout = */ -1,
+       plugin_flush (/* plugin = */ NULL,
+                       /* timeout = */ 0,
                        /* identifier = */ NULL);
 
        le = NULL;
@@ -1384,16 +1379,17 @@ int plugin_dispatch_values (value_list_t *vl)
        }
 
        if (vl->time == 0)
-               vl->time = time (NULL);
+               vl->time = cdtime ();
 
        if (vl->interval <= 0)
                vl->interval = interval_g;
 
-       DEBUG ("plugin_dispatch_values: time = %u; interval = %i; "
+       DEBUG ("plugin_dispatch_values: time = %.3f; interval = %.3f; "
                        "host = %s; "
                        "plugin = %s; plugin_instance = %s; "
                        "type = %s; type_instance = %s;",
-                       (unsigned int) vl->time, vl->interval,
+                       CDTIME_T_TO_DOUBLE (vl->time),
+                       CDTIME_T_TO_DOUBLE (vl->interval),
                        vl->host,
                        vl->plugin, vl->plugin_instance,
                        vl->type, vl->type_instance);
@@ -1518,9 +1514,9 @@ int plugin_dispatch_notification (const notification_t *notif)
        /* Possible TODO: Add flap detection here */
 
        DEBUG ("plugin_dispatch_notification: severity = %i; message = %s; "
-                       "time = %u; host = %s;",
+                       "time = %.3f; host = %s;",
                        notif->severity, notif->message,
-                       (unsigned int) notif->time, notif->host);
+                       CDTIME_T_TO_DOUBLE (notif->time), notif->host);
 
        /* Nobody cares for notifications */
        if (list_notification == NULL)
index d78aa4f..490aed0 100644 (file)
@@ -25,6 +25,7 @@
 #include "collectd.h"
 #include "configfile.h"
 #include "meta_data.h"
+#include "utils_time.h"
 
 #define PLUGIN_FLAGS_GLOBAL 0x0001
 
@@ -85,8 +86,8 @@ struct value_list_s
 {
        value_t *values;
        int      values_len;
-       time_t   time;
-       int      interval;
+       cdtime_t time;
+       cdtime_t interval;
        char     host[DATA_MAX_NAME_LEN];
        char     plugin[DATA_MAX_NAME_LEN];
        char     plugin_instance[DATA_MAX_NAME_LEN];
@@ -143,7 +144,7 @@ typedef struct notification_meta_s
 typedef struct notification_s
 {
        int    severity;
-       time_t time;
+       cdtime_t time;
        char   message[NOTIF_MAX_MSG_LEN];
        char   host[DATA_MAX_NAME_LEN];
        char   plugin[DATA_MAX_NAME_LEN];
@@ -167,7 +168,7 @@ typedef int (*plugin_init_cb) (void);
 typedef int (*plugin_read_cb) (user_data_t *);
 typedef int (*plugin_write_cb) (const data_set_t *, const value_list_t *,
                user_data_t *);
-typedef int (*plugin_flush_cb) (int timeout, const char *identifier,
+typedef int (*plugin_flush_cb) (cdtime_t timeout, const char *identifier,
                user_data_t *);
 typedef void (*plugin_log_cb) (int severity, const char *message,
                user_data_t *);
@@ -248,7 +249,7 @@ void plugin_shutdown_all (void);
 int plugin_write (const char *plugin,
     const data_set_t *ds, const value_list_t *vl);
 
-int plugin_flush (const char *plugin, int timeout, const char *identifier);
+int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier);
 
 /*
  * The `plugin_register_*' functions are used to make `config', `init',
index 175cc09..a8812e2 100644 (file)
@@ -117,7 +117,7 @@ typedef struct {
        udb_query_t    **queries;
        size_t           queries_num;
 
-       int interval;
+       cdtime_t interval;
 
        char *host;
        char *port;
@@ -335,8 +335,9 @@ static PGresult *c_psql_exec_query_params (c_psql_database_t *db,
                                params[i] = db->user;
                                break;
                        case C_PSQL_PARAM_INTERVAL:
-                               ssnprintf (interval, sizeof (interval), "%i",
-                                               db->interval > 0 ? db->interval : interval_g);
+                               ssnprintf (interval, sizeof (interval), "%.3f",
+                                               (db->interval > 0)
+                                               ? CDTIME_T_TO_DOUBLE (db->interval) : interval_g);
                                params[i] = interval;
                                break;
                        default:
@@ -535,28 +536,6 @@ static int config_set_s (char *name, char **var, const oconfig_item_t *ci)
        return 0;
 } /* config_set_s */
 
-static int config_set_i (char *name, int *var,
-               const oconfig_item_t *ci, int min)
-{
-       int value;
-
-       if ((0 != ci->children_num) || (1 != ci->values_num)
-                       || (OCONFIG_TYPE_NUMBER != ci->values[0].type)) {
-               log_err ("%s expects a single number argument.", name);
-               return 1;
-       }
-
-       value = (int)ci->values[0].value.number;
-
-       if (value < min) {
-               log_err ("%s expects a number greater or equal to %i.", name, min);
-               return 1;
-       }
-
-       *var = value;
-       return 0;
-} /* config_set_s */
-
 static int config_query_param_add (udb_query_t *q, oconfig_item_t *ci)
 {
        c_psql_user_data_t *data;
@@ -618,7 +597,7 @@ static int c_psql_config_database (oconfig_item_t *ci)
        c_psql_database_t *db;
 
        char cb_name[DATA_MAX_NAME_LEN];
-       struct timespec cb_interval;
+       struct timespec cb_interval = { 0, 0 };
        user_data_t ud;
 
        int i;
@@ -656,7 +635,7 @@ static int c_psql_config_database (oconfig_item_t *ci)
                        udb_query_pick_from_list (c, queries, queries_num,
                                        &db->queries, &db->queries_num);
                else if (0 == strcasecmp (c->key, "Interval"))
-                       config_set_i ("Interval", &db->interval, c, /* min = */ 1);
+                       cf_util_get_cdtime (c, &db->interval);
                else
                        log_warn ("Ignoring unknown config key \"%s\".", c->key);
        }
@@ -701,12 +680,11 @@ static int c_psql_config_database (oconfig_item_t *ci)
 
        ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->database);
 
-       memset (&cb_interval, 0, sizeof (cb_interval));
-       if (db->interval > 0)
-               cb_interval.tv_sec = (time_t)db->interval;
+       CDTIME_T_TO_TIMESPEC (db->interval, &cb_interval);
 
        plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
-                       /* interval = */ &cb_interval, &ud);
+                       /* interval = */ (db->interval > 0) ? &cb_interval : NULL,
+                       &ud);
        return 0;
 } /* c_psql_config_database */
 
index 29f6bca..a1b2355 100644 (file)
@@ -321,6 +321,9 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */
 
   struct sockaddr_un sa_unix;
 
+  struct timeval stv_timeout;
+  cdtime_t cdt_timeout;
+
   sd = socket (PF_UNIX, item->socktype, 0);
   if (sd < 0)
   {
@@ -361,12 +364,13 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */
       break;
     }
 
-    struct timeval timeout;
-    timeout.tv_sec=2;
-    if (timeout.tv_sec < interval_g * 3 / 4)
-      timeout.tv_sec = interval_g * 3 / 4;
-    timeout.tv_usec=0;
-    status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof (timeout));
+    cdt_timeout = interval_g * 3 / 4;
+    if (cdt_timeout < TIME_T_TO_CDTIME_T (2))
+      cdt_timeout = TIME_T_TO_CDTIME_T (2);
+
+    CDTIME_T_TO_TIMEVAL (cdt_timeout, &stv_timeout);
+
+    status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &stv_timeout, sizeof (stv_timeout));
     if (status != 0)
     {
       FUNC_ERROR ("setsockopt");
index c056b5b..eed0591 100644 (file)
@@ -435,8 +435,8 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                sstrncpy(v->data.type_instance, value_list->type_instance, sizeof(v->data.type_instance));
                sstrncpy(v->data.plugin, value_list->plugin, sizeof(v->data.plugin));
                sstrncpy(v->data.plugin_instance, value_list->plugin_instance, sizeof(v->data.plugin_instance));
-               v->data.time = value_list->time;
-               v->interval = value_list->interval;
+               v->data.time = CDTIME_T_TO_DOUBLE(value_list->time);
+               v->interval = CDTIME_T_TO_DOUBLE(value_list->interval);
                Py_CLEAR(v->values);
                v->values = list;
                Py_CLEAR(v->meta);
@@ -465,7 +465,7 @@ static int cpy_notification_callback(const notification_t *notification, user_da
                sstrncpy(n->data.type_instance, notification->type_instance, sizeof(n->data.type_instance));
                sstrncpy(n->data.plugin, notification->plugin, sizeof(n->data.plugin));
                sstrncpy(n->data.plugin_instance, notification->plugin_instance, sizeof(n->data.plugin_instance));
-               n->data.time = notification->time;
+               n->data.time = CDTIME_T_TO_DOUBLE(notification->time);
                sstrncpy(n->message, notification->message, sizeof(n->message));
                n->severity = notification->severity;
                ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data, (void *) 0); /* New reference. */
index cc7e296..36a717e 100644 (file)
@@ -91,7 +91,7 @@ static PyObject *cpy_common_repr(PyObject *s) {
 
        if (self->time != 0) {
                CPY_STRCAT(&ret, l_time);
-               tmp = PyInt_FromLong(self->time);
+               tmp = PyFloat_FromDouble(self->time);
                CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp);
                CPY_STRCAT_AND_DEL(&ret, tmp);
        }
@@ -351,14 +351,13 @@ static PyObject *Values_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
 static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) {
        Values *self = (Values *) s;
-       int interval = 0;
-       double time = 0;
+       double interval = 0, time = 0;
        PyObject *values = NULL, *meta = NULL, *tmp;
        const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = "";
        static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", "meta", NULL};
        
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist,
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
                        NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
                        NULL, &plugin, NULL, &host, &time, &interval, &meta))
                return -1;
@@ -485,8 +484,7 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        value_t *value;
        value_list_t value_list = VALUE_LIST_INIT;
        PyObject *values = self->values, *meta = self->meta;
-       double time = self->data.time;
-       int interval = self->interval;
+       double time = self->data.time, interval = self->interval;
        const char *host = self->data.host;
        const char *plugin = self->data.plugin;
        const char *plugin_instance = self->data.plugin_instance;
@@ -495,7 +493,7 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        
        static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", "meta", NULL};
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist,
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
                        NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
                        NULL, &plugin, NULL, &host, &time, &interval, &meta))
                return NULL;
@@ -559,8 +557,8 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        value_list.values = value;
        value_list.meta = cpy_build_meta(meta);
        value_list.values_len = size;
-       value_list.time = time;
-       value_list.interval = interval;
+       value_list.time = DOUBLE_TO_CDTIME_T(time);
+       value_list.interval = DOUBLE_TO_CDTIME_T(interval);
        sstrncpy(value_list.host, host, sizeof(value_list.host));
        sstrncpy(value_list.plugin, plugin, sizeof(value_list.plugin));
        sstrncpy(value_list.plugin_instance, plugin_instance, sizeof(value_list.plugin_instance));
@@ -588,8 +586,7 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        value_t *value;
        value_list_t value_list = VALUE_LIST_INIT;
        PyObject *values = self->values, *meta = self->meta;
-       double time = self->data.time;
-       int interval = self->interval;
+       double time = self->data.time, interval = self->interval;
        const char *host = self->data.host;
        const char *plugin = self->data.plugin;
        const char *plugin_instance = self->data.plugin_instance;
@@ -599,7 +596,7 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        
        static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", "meta", NULL};
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist,
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
                        NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
                        NULL, &plugin, NULL, &host, &time, &interval, &meta))
                return NULL;
@@ -658,8 +655,8 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        }
        value_list.values = value;
        value_list.values_len = size;
-       value_list.time = time;
-       value_list.interval = interval;
+       value_list.time = DOUBLE_TO_CDTIME_T(time);
+       value_list.interval = DOUBLE_TO_CDTIME_T(interval);
        sstrncpy(value_list.host, host, sizeof(value_list.host));
        sstrncpy(value_list.plugin, plugin, sizeof(value_list.plugin));
        sstrncpy(value_list.plugin_instance, plugin_instance, sizeof(value_list.plugin_instance));
@@ -701,7 +698,7 @@ static PyObject *Values_repr(PyObject *s) {
        ret = cpy_common_repr(s);
        if (self->interval != 0) {
                CPY_STRCAT(&ret, l_interval);
-               tmp = PyInt_FromLong(self->interval);
+               tmp = PyFloat_FromDouble(self->interval);
                CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp);
                CPY_STRCAT_AND_DEL(&ret, tmp);
        }
@@ -864,7 +861,7 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj
                return NULL;
        }
 
-       notification.time = t;
+       notification.time = DOUBLE_TO_CDTIME_T(t);
        notification.severity = severity;
        sstrncpy(notification.message, message, sizeof(notification.message));
        sstrncpy(notification.host, host, sizeof(notification.host));
@@ -873,8 +870,8 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj
        sstrncpy(notification.type, type, sizeof(notification.type));
        sstrncpy(notification.type_instance, type_instance, sizeof(notification.type_instance));
        notification.meta = NULL;
-       if (notification.time < 1)
-               notification.time = time(0);
+       if (notification.time == 0)
+               notification.time = cdtime();
        if (notification.host[0] == 0)
                sstrncpy(notification.host, hostname_g, sizeof(notification.host));
        if (notification.plugin[0] == 0)
index 34e860b..fb7eb79 100644 (file)
@@ -64,12 +64,14 @@ static int value_list_to_string (char *buffer, int buffer_len,
   int offset;
   int status;
   int i;
+  time_t t;
 
   assert (0 == strcmp (ds->type, vl->type));
 
   memset (buffer, '\0', buffer_len);
 
-  status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time);
+  t = CDTIME_T_TO_TIME_T (vl->time);
+  status = ssnprintf (buffer, buffer_len, "%lu", (unsigned long) t);
   if ((status < 1) || (status >= buffer_len))
     return (-1);
   offset = status;
index cb8ad59..b366a9c 100644 (file)
  */
 struct rrd_cache_s
 {
-       int    values_num;
-       char **values;
-       time_t first_value;
-       time_t last_value;
-       int random_variation;
+       int      values_num;
+       char   **values;
+       cdtime_t first_value;
+       cdtime_t last_value;
+       int64_t  random_variation;
        enum
        {
                FLAG_NONE   = 0x00,
@@ -107,10 +107,10 @@ static rrdcreate_config_t rrdcreate_config =
 
 /* XXX: If you need to lock both, cache_lock and queue_lock, at the same time,
  * ALWAYS lock `cache_lock' first! */
-static int         cache_timeout = 0;
-static int         cache_flush_timeout = 0;
-static int         random_timeout = 1;
-static time_t      cache_flush_last;
+static cdtime_t    cache_timeout = 0;
+static cdtime_t    cache_flush_timeout = 0;
+static cdtime_t    random_timeout = TIME_T_TO_CDTIME_T (1);
+static cdtime_t    cache_flush_last;
 static c_avl_tree_t *cache = NULL;
 static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
 
@@ -199,11 +199,13 @@ static int value_list_to_string (char *buffer, int buffer_len,
 {
        int offset;
        int status;
+       time_t tt;
        int i;
 
        memset (buffer, '\0', buffer_len);
 
-       status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) vl->time);
+       tt = CDTIME_T_TO_TIME_T (vl->time);
+       status = ssnprintf (buffer, buffer_len, "%u", (unsigned int) tt);
        if ((status < 1) || (status >= buffer_len))
                return (-1);
        offset = status;
@@ -510,10 +512,11 @@ static int rrd_queue_dequeue (const char *filename,
   return (0);
 } /* int rrd_queue_dequeue */
 
-static void rrd_cache_flush (int timeout)
+/* XXX: You must hold "cache_lock" when calling this function! */
+static void rrd_cache_flush (cdtime_t timeout)
 {
        rrd_cache_t *rc;
-       time_t       now;
+       cdtime_t     now;
 
        char **keys = NULL;
        int    keys_num = 0;
@@ -522,9 +525,11 @@ static void rrd_cache_flush (int timeout)
        c_avl_iterator_t *iter;
        int i;
 
-       DEBUG ("rrdtool plugin: Flushing cache, timeout = %i", timeout);
+       DEBUG ("rrdtool plugin: Flushing cache, timeout = %.3f",
+                       CDTIME_T_TO_DOUBLE (timeout));
 
-       now = time (NULL);
+       now = cdtime ();
+       timeout = TIME_T_TO_CDTIME_T (timeout);
 
        /* Build a list of entries to be flushed */
        iter = c_avl_get_iterator (cache);
@@ -532,7 +537,9 @@ static void rrd_cache_flush (int timeout)
        {
                if (rc->flags != FLAG_NONE)
                        continue;
-               else if ((now - rc->first_value) < timeout)
+               /* timeout == 0  =>  flush everything */
+               else if ((timeout != 0)
+                               && ((now - rc->first_value) < timeout))
                        continue;
                else if (rc->values_num > 0)
                {
@@ -585,10 +592,11 @@ static void rrd_cache_flush (int timeout)
        cache_flush_last = now;
 } /* void rrd_cache_flush */
 
-static int rrd_cache_flush_identifier (int timeout, const char *identifier)
+static int rrd_cache_flush_identifier (cdtime_t timeout,
+    const char *identifier)
 {
   rrd_cache_t *rc;
-  time_t now;
+  cdtime_t now;
   int status;
   char key[2048];
 
@@ -598,7 +606,7 @@ static int rrd_cache_flush_identifier (int timeout, const char *identifier)
     return (0);
   }
 
-  now = time (NULL);
+  now = cdtime ();
 
   if (datadir == NULL)
     snprintf (key, sizeof (key), "%s.rrd",
@@ -642,8 +650,43 @@ static int rrd_cache_flush_identifier (int timeout, const char *identifier)
   return (status);
 } /* int rrd_cache_flush_identifier */
 
+static int64_t rrd_get_random_variation (void)
+{
+  double dbl_timeout;
+  cdtime_t ctm_timeout;
+  double rand_fact;
+  _Bool negative;
+  int64_t ret;
+
+  if (random_timeout <= 0)
+    return (0);
+
+  /* Assure that "cache_timeout + random_variation" is never negative. */
+  if (random_timeout > cache_timeout)
+  {
+         INFO ("rrdtool plugin: Adjusting \"RandomTimeout\" to %.3f seconds.",
+                         CDTIME_T_TO_DOUBLE (cache_timeout));
+         random_timeout = cache_timeout;
+  }
+
+  /* This seems a bit complicated, but "random_timeout" is likely larger than
+   * RAND_MAX, so we can't simply use modulo here. */
+  dbl_timeout = CDTIME_T_TO_DOUBLE (random_timeout);
+  rand_fact = ((double) random ())
+    / ((double) RAND_MAX);
+  negative = (_Bool) (random () % 2);
+
+  ctm_timeout = DOUBLE_TO_CDTIME_T (dbl_timeout * rand_fact);
+
+  ret = (int64_t) ctm_timeout;
+  if (negative)
+    ret *= -1;
+
+  return (ret);
+} /* int64_t rrd_get_random_variation */
+
 static int rrd_cache_insert (const char *filename,
-               const char *value, time_t value_time)
+               const char *value, cdtime_t value_time)
 {
        rrd_cache_t *rc = NULL;
        int new_rc = 0;
@@ -664,14 +707,14 @@ static int rrd_cache_insert (const char *filename,
 
        if (rc == NULL)
        {
-               rc = (rrd_cache_t *) malloc (sizeof (rrd_cache_t));
+               rc = malloc (sizeof (*rc));
                if (rc == NULL)
                        return (-1);
                rc->values_num = 0;
                rc->values = NULL;
                rc->first_value = 0;
                rc->last_value = 0;
-               rc->random_variation = 0;
+               rc->random_variation = rrd_get_random_variation ();
                rc->flags = FLAG_NONE;
                new_rc = 1;
        }
@@ -679,9 +722,9 @@ static int rrd_cache_insert (const char *filename,
        if (rc->last_value >= value_time)
        {
                pthread_mutex_unlock (&cache_lock);
-               DEBUG ("rrdtool plugin: (rc->last_value = %u) >= (value_time = %u)",
-                               (unsigned int) rc->last_value,
-                               (unsigned int) value_time);
+               DEBUG ("rrdtool plugin: (rc->last_value = %"PRIu64") "
+                               ">= (value_time = %"PRIu64")",
+                               rc->last_value, value_time);
                return (-1);
        }
 
@@ -738,11 +781,11 @@ static int rrd_cache_insert (const char *filename,
        }
 
        DEBUG ("rrdtool plugin: rrd_cache_insert: file = %s; "
-                       "values_num = %i; age = %lu;",
+                       "values_num = %i; age = %.3f;",
                        filename, rc->values_num,
-                       (unsigned long)(rc->last_value - rc->first_value));
+                       CDTIME_T_TO_DOUBLE (rc->last_value - rc->first_value));
 
-       if ((rc->last_value + rc->random_variation - rc->first_value) >= cache_timeout)
+       if ((rc->last_value - rc->first_value) >= (cache_timeout + rc->random_variation))
        {
                /* XXX: If you need to lock both, cache_lock and queue_lock, at
                 * the same time, ALWAYS lock `cache_lock' first! */
@@ -754,17 +797,7 @@ static int rrd_cache_insert (const char *filename,
                        if (status == 0)
                                rc->flags = FLAG_QUEUED;
 
-                       /* Update the jitter value. Negative values are
-                        * slightly preferred. */
-                       if (random_timeout > 0)
-                       {
-                               rc->random_variation = (rand () % (2 * random_timeout))
-                                       - random_timeout;
-                       }
-                       else
-                       {
-                               rc->random_variation = 0;
-                       }
+                        rc->random_variation = rrd_get_random_variation ();
                }
                else
                {
@@ -773,7 +806,7 @@ static int rrd_cache_insert (const char *filename,
        }
 
        if ((cache_timeout > 0) &&
-                       ((time (NULL) - cache_flush_last) > cache_flush_timeout))
+                       ((cdtime () - cache_flush_last) > cache_flush_timeout))
                rrd_cache_flush (cache_flush_timeout);
 
        pthread_mutex_unlock (&cache_lock);
@@ -899,8 +932,8 @@ static int rrd_write (const data_set_t *ds, const value_list_t *vl,
        return (status);
 } /* int rrd_write */
 
-static int rrd_flush (int timeout, const char *identifier,
-               user_data_t __attribute__((unused)) *user_data)
+static int rrd_flush (cdtime_t timeout, const char *identifier,
+               __attribute__((unused)) user_data_t *user_data)
 {
        pthread_mutex_lock (&cache_lock);
 
@@ -919,7 +952,7 @@ static int rrd_config (const char *key, const char *value)
 {
        if (strcasecmp ("CacheTimeout", key) == 0)
        {
-               int tmp = atoi (value);
+               double tmp = atof (value);
                if (tmp < 0)
                {
                        fprintf (stderr, "rrdtool: `CacheTimeout' must "
@@ -928,7 +961,7 @@ static int rrd_config (const char *key, const char *value)
                                        "be greater than 0.\n");
                        return (1);
                }
-               cache_timeout = tmp;
+               cache_timeout = DOUBLE_TO_CDTIME_T (tmp);
        }
        else if (strcasecmp ("CacheFlush", key) == 0)
        {
@@ -1061,10 +1094,10 @@ static int rrd_config (const char *key, const char *value)
        }
        else if (strcasecmp ("RandomTimeout", key) == 0)
         {
-               int tmp;
+               double tmp;
 
-               tmp = atoi (value);
-               if (tmp < 0)
+               tmp = atof (value);
+               if (tmp < 0.0)
                {
                        fprintf (stderr, "rrdtool: `RandomTimeout' must "
                                        "be greater than or equal to zero.\n");
@@ -1073,7 +1106,7 @@ static int rrd_config (const char *key, const char *value)
                }
                else
                {
-                       random_timeout = tmp;
+                       random_timeout = DOUBLE_TO_CDTIME_T (tmp);
                }
        }
        else
@@ -1086,7 +1119,7 @@ static int rrd_config (const char *key, const char *value)
 static int rrd_shutdown (void)
 {
        pthread_mutex_lock (&cache_lock);
-       rrd_cache_flush (-1);
+       rrd_cache_flush (0);
        pthread_mutex_unlock (&cache_lock);
 
        pthread_mutex_lock (&queue_lock);
@@ -1134,12 +1167,12 @@ static int rrd_init (void)
                rrdcreate_config.heartbeat = 2 * rrdcreate_config.stepsize;
 
        if ((rrdcreate_config.heartbeat > 0)
-                       && (rrdcreate_config.heartbeat < interval_g))
+                       && (rrdcreate_config.heartbeat < CDTIME_T_TO_TIME_T (interval_g)))
                WARNING ("rrdtool plugin: Your `heartbeat' is "
                                "smaller than your `interval'. This will "
                                "likely cause problems.");
        else if ((rrdcreate_config.stepsize > 0)
-                       && (rrdcreate_config.stepsize < interval_g))
+                       && (rrdcreate_config.stepsize < CDTIME_T_TO_TIME_T (interval_g)))
                WARNING ("rrdtool plugin: Your `stepsize' is "
                                "smaller than your `interval'. This will "
                                "create needlessly big RRD-files.");
@@ -1154,10 +1187,9 @@ static int rrd_init (void)
                return (-1);
        }
 
-       cache_flush_last = time (NULL);
-       if (cache_timeout < 2)
+       cache_flush_last = cdtime ();
+       if (cache_timeout == 0)
        {
-               cache_timeout = 0;
                cache_flush_timeout = 0;
        }
        else if (cache_flush_timeout < cache_timeout)
index 1c2828c..54bcf67 100644 (file)
@@ -69,7 +69,7 @@ struct host_definition_s
   int version;
   void *sess_handle;
   c_complain_t complaint;
-  uint32_t interval;
+  cdtime_t interval;
   data_definition_t **data_list;
   int data_list_len;
 };
@@ -159,7 +159,6 @@ static void csnmp_host_definition_destroy (void *arg) /* {{{ */
  *      +-> csnmp_config_add_host_community
  *      +-> csnmp_config_add_host_version
  *      +-> csnmp_config_add_host_collect
- *      +-> csnmp_config_add_host_interval
  */
 static void call_snmp_init_once (void)
 {
@@ -543,22 +542,6 @@ static int csnmp_config_add_host_collect (host_definition_t *host,
   return (0);
 } /* int csnmp_config_add_host_collect */
 
-static int csnmp_config_add_host_interval (host_definition_t *hd, oconfig_item_t *ci)
-{
-  if ((ci->values_num != 1)
-      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
-  {
-    WARNING ("snmp plugin: The `Interval' config option needs exactly one number argument.");
-    return (-1);
-  }
-
-  hd->interval = ci->values[0].value.number >= 0
-    ? (uint32_t) ci->values[0].value.number
-    : 0;
-
-  return (0);
-} /* int csnmp_config_add_host_interval */
-
 static int csnmp_config_add_host (oconfig_item_t *ci)
 {
   host_definition_t *hd;
@@ -607,7 +590,7 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
     else if (strcasecmp ("Collect", option->key) == 0)
       csnmp_config_add_host_collect (hd, option);
     else if (strcasecmp ("Interval", option->key) == 0)
-      csnmp_config_add_host_interval (hd, option);
+      cf_util_get_cdtime (option, &hd->interval);
     else
     {
       WARNING ("snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.", option->key);
@@ -651,9 +634,7 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
   cb_data.data = hd;
   cb_data.free_func = csnmp_host_definition_destroy;
 
-  memset (&cb_interval, 0, sizeof (cb_interval));
-  if (hd->interval != 0)
-    cb_interval.tv_sec = (time_t) hd->interval;
+  CDTIME_T_TO_TIMESPEC (hd->interval, &cb_interval);
 
   status = plugin_register_complex_read (/* group = */ NULL, cb_name,
       csnmp_read_host, /* interval = */ &cb_interval,
@@ -1529,8 +1510,8 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
 static int csnmp_read_host (user_data_t *ud)
 {
   host_definition_t *host;
-  time_t time_start;
-  time_t time_end;
+  cdtime_t time_start;
+  cdtime_t time_end;
   int status;
   int success;
   int i;
@@ -1540,9 +1521,7 @@ static int csnmp_read_host (user_data_t *ud)
   if (host->interval == 0)
     host->interval = interval_g;
 
-  time_start = time (NULL);
-  DEBUG ("snmp plugin: csnmp_read_host (%s) started at %u;", host->name,
-      (unsigned int) time_start);
+  time_start = cdtime ();
 
   if (host->sess_handle == NULL)
     csnmp_host_open_session (host);
@@ -1564,14 +1543,14 @@ static int csnmp_read_host (user_data_t *ud)
       success++;
   }
 
-  time_end = time (NULL);
-  DEBUG ("snmp plugin: csnmp_read_host (%s) finished at %u;", host->name,
-      (unsigned int) time_end);
-  if ((uint32_t) (time_end - time_start) > host->interval)
+  time_end = cdtime ();
+  if ((time_end - time_start) > host->interval)
   {
-    WARNING ("snmp plugin: Host `%s' should be queried every %"PRIu32
-       " seconds, but reading all values takes %u seconds.",
-       host->name, host->interval, (unsigned int) (time_end - time_start));
+    WARNING ("snmp plugin: Host `%s' should be queried every %.3f "
+       "seconds, but reading all values takes %.3f seconds.",
+       host->name,
+       CDTIME_T_TO_DOUBLE (host->interval),
+       CDTIME_T_TO_DOUBLE (time_end - time_start));
   }
 
   if (success == 0)
index 96598af..cb68048 100644 (file)
@@ -209,7 +209,7 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
   /* Initialize the structure. */
   memset (&n, 0, sizeof (n));
   n.severity = data->severity;
-  n.time = time (NULL);
+  n.time = cdtime ();
   sstrncpy (n.message, data->message, sizeof (n.message));
   sstrncpy (n.host, vl->host, sizeof (n.host));
   sstrncpy (n.plugin, vl->plugin, sizeof (n.plugin));
index 29fecdf..af224f1 100644 (file)
@@ -96,7 +96,7 @@ static int ts_invoke_counter (const data_set_t *ds, value_list_t *vl, /* {{{ */
                {
                        difference = curr_counter - prev_counter;
                }
-               rate = ((double) difference) / ((double) vl->interval);
+               rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval);
 
                /* Modify the rate. */
                if (!isnan (data->factor))
@@ -105,7 +105,7 @@ static int ts_invoke_counter (const data_set_t *ds, value_list_t *vl, /* {{{ */
                        rate += data->offset;
 
                /* Calculate the internal counter. */
-               int_fraction += (rate * ((double) vl->interval));
+               int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
                difference = (uint64_t) int_fraction;
                int_fraction -= ((double) difference);
                int_counter  += difference;
@@ -199,7 +199,7 @@ static int ts_invoke_derive (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
                /* Calcualte the rate */
                difference = curr_derive - prev_derive;
-               rate = ((double) difference) / ((double) vl->interval);
+               rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval);
 
                /* Modify the rate. */
                if (!isnan (data->factor))
@@ -208,7 +208,7 @@ static int ts_invoke_derive (const data_set_t *ds, value_list_t *vl, /* {{{ */
                        rate += data->offset;
 
                /* Calculate the internal derive. */
-               int_fraction += (rate * ((double) vl->interval));
+               int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
                if (int_fraction < 0.0) /* handle negative integer rounding correctly */
                        difference = ((int64_t) int_fraction) - 1;
                else
@@ -263,7 +263,7 @@ static int ts_invoke_absolute (const data_set_t *ds, value_list_t *vl, /* {{{ */
        if (status != 0)
                int_fraction = 0.0;
 
-       rate = ((double) curr_absolute) / ((double) vl->interval);
+       rate = ((double) curr_absolute) / CDTIME_T_TO_DOUBLE (vl->interval);
 
        /* Modify the rate. */
        if (!isnan (data->factor))
@@ -272,7 +272,7 @@ static int ts_invoke_absolute (const data_set_t *ds, value_list_t *vl, /* {{{ */
                rate += data->offset;
 
        /* Calculate the new absolute. */
-       int_fraction += (rate * ((double) vl->interval));
+       int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
        curr_absolute = (uint64_t) int_fraction;
        int_fraction -= ((double) curr_absolute);
 
index b9d07bf..0ad0d90 100644 (file)
 # error "This module is for Linux only."
 #endif
 
+static const char *config_keys[] = {
+       "Device",
+       "IgnoreSelected",
+       "ForceUseProcfs"
+};
+
 const char *const dirname_sysfs = "/sys/class/thermal";
 const char *const dirname_procfs = "/proc/acpi/thermal_zone";
 
-static char force_procfs = 0;
+static _Bool force_procfs = 0;
 static ignorelist_t *device_list;
-static value_list_t vl_temp_template = VALUE_LIST_STATIC;
-static value_list_t vl_state_template = VALUE_LIST_STATIC;
 
 enum dev_type {
        TEMP = 0,
@@ -45,16 +49,18 @@ enum dev_type {
 static void thermal_submit (const char *plugin_instance, enum dev_type dt,
                gauge_t value)
 {
-       value_list_t vl = (dt == TEMP) ? vl_temp_template : vl_state_template;
-       value_t vt;
+       value_list_t vl = VALUE_LIST_INIT;
+       value_t v;
 
-       vt.gauge = value;
+       v.gauge = value;
+       vl.values = &v;
 
-       vl.values = &vt;
        sstrncpy (vl.plugin, "thermal", sizeof(vl.plugin));
-       sstrncpy (vl.plugin_instance, plugin_instance,
-                       sizeof(vl.plugin_instance));
-       sstrncpy (vl.type, (dt == TEMP) ? "temperature" : "gauge",
+       if (plugin_instance != NULL)
+               sstrncpy (vl.plugin_instance, plugin_instance,
+                               sizeof (vl.plugin_instance));
+       sstrncpy (vl.type,
+                       (dt == TEMP) ? "temperature" : "gauge",
                        sizeof (vl.type));
 
        plugin_dispatch_values (&vl);
@@ -66,7 +72,7 @@ static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir,
        char filename[256];
        char data[1024];
        int len;
-       int ok = 0;
+       _Bool success = 0;
 
        if (device_list && ignorelist_match (device_list, name))
                return -1;
@@ -87,7 +93,7 @@ static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir,
 
                if (endptr == data + len && errno == 0) {
                        thermal_submit(name, TEMP, temp);
-                       ++ok;
+                       success = 1;
                }
        }
 
@@ -107,11 +113,11 @@ static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir,
 
                if (endptr == data + len && errno == 0) {
                        thermal_submit(name, COOLING_DEV, state);
-                       ++ok;
+                       success = 1;
                }
        }
 
-       return ok ? 0 : -1;
+       return (success ? 0 : -1);
 }
 
 static int thermal_procfs_device_read (const char __attribute__((unused)) *dir,
@@ -141,17 +147,17 @@ static int thermal_procfs_device_read (const char __attribute__((unused)) *dir,
                        && (! strncmp(data, str_temp, sizeof(str_temp)-1))) {
                char *endptr = NULL;
                double temp;
-               double celsius, add;
+               double factor, add;
                
                if (data[--len] == 'C') {
                        add = 0;
-                       celsius = 1;
+                       factor = 1.0;
                } else if (data[len] == 'F') {
                        add = -32;
-                       celsius = 5/9;
+                       factor = 5.0/9.0;
                } else if (data[len] == 'K') {
                        add = -273.15;
-                       celsius = 1;
+                       factor = 1.0;
                } else
                        return -1;
 
@@ -164,7 +170,7 @@ static int thermal_procfs_device_read (const char __attribute__((unused)) *dir,
                ++len;
 
                errno = 0;
-               temp = (strtod (data + len, &endptr) + add) * celsius;
+               temp = (strtod (data + len, &endptr) + add) * factor;
 
                if (endptr != data + len && errno == 0) {
                        thermal_submit(name, TEMP, temp);
@@ -175,12 +181,6 @@ static int thermal_procfs_device_read (const char __attribute__((unused)) *dir,
        return -1;
 }
 
-static const char *config_keys[] = {
-       "Device",
-       "IgnoreSelected",
-       "ForceUseProcfs"
-};
-
 static int thermal_config (const char *key, const char *value)
 {
        if (device_list == NULL)
@@ -237,21 +237,6 @@ static int thermal_init (void)
                ret = plugin_register_read ("thermal", thermal_procfs_read);
        }
 
-       if (!ret) {
-               vl_temp_template.values_len = 1;
-               vl_temp_template.interval = interval_g;
-               sstrncpy (vl_temp_template.host, hostname_g,
-                       sizeof(vl_temp_template.host));
-               sstrncpy (vl_temp_template.plugin, "thermal",
-                       sizeof(vl_temp_template.plugin));
-               sstrncpy (vl_temp_template.type_instance, "temperature",
-                       sizeof(vl_temp_template.type_instance));
-
-               vl_state_template = vl_temp_template;
-               sstrncpy (vl_state_template.type_instance, "cooling_state",
-                       sizeof(vl_state_template.type_instance));
-       }
-
        return ret;
 }
 
index aeb662d..20b1237 100644 (file)
@@ -38,13 +38,13 @@ typedef struct cache_entry_s
        value_t   *values_raw;
        /* Time contained in the package
         * (for calculating rates) */
-       time_t last_time;
+       cdtime_t last_time;
        /* Time according to the local clock
         * (for purging old entries) */
-       time_t last_update;
+       cdtime_t last_update;
        /* Interval in which the data is collected
         * (for purding old entries) */
-       int interval;
+       cdtime_t interval;
        int state;
        int hits;
 
@@ -164,7 +164,7 @@ static int uc_send_notification (const char *name)
    * acquiring the lock takes and we will use this time later to decide
    * whether or not the state is OKAY.
    */
-  n.time = time (NULL);
+  n.time = cdtime ();
 
   status = c_avl_get (cache_tree, name, (void *) &ce);
   if (status != 0)
@@ -184,8 +184,8 @@ static int uc_send_notification (const char *name)
   }
 
   ssnprintf (n.message, sizeof (n.message),
-      "%s has not been updated for %i seconds.", name,
-      (int) (n.time - ce->last_update));
+      "%s has not been updated for %.3f seconds.", name,
+      CDTIME_T_TO_DOUBLE (n.time - ce->last_update));
 
   pthread_mutex_unlock (&cache_lock);
 
@@ -258,7 +258,7 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl,
        ce->values_gauge[i] = NAN;
        if (vl->interval > 0)
          ce->values_gauge[i] = ((double) vl->values[i].absolute)
-           / ((double) vl->interval);
+           / CDTIME_T_TO_DOUBLE (vl->interval);
        ce->values_raw[i].absolute = vl->values[i].absolute;
        break;
        
@@ -274,7 +274,7 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl,
   uc_check_range (ds, ce);
 
   ce->last_time = vl->time;
-  ce->last_update = time (NULL);
+  ce->last_update = cdtime ();
   ce->interval = vl->interval;
   ce->state = STATE_OKAY;
 
@@ -300,7 +300,7 @@ int uc_init (void)
 
 int uc_check_timeout (void)
 {
-  time_t now;
+  cdtime_t now;
   cache_entry_t *ce;
 
   char **keys = NULL;
@@ -312,14 +312,14 @@ int uc_check_timeout (void)
   
   pthread_mutex_lock (&cache_lock);
 
-  now = time (NULL);
+  now = cdtime ();
 
   /* Build a list of entries to be flushed */
   iter = c_avl_get_iterator (cache_tree);
   while (c_avl_iterator_next (iter, (void *) &key, (void *) &ce) == 0)
   {
     /* If entry has not been updated, add to `keys' array */
-    if ((now - ce->last_update) >= (timeout_g * ce->interval))
+    if ((now - ce->last_update) >= (ce->interval * timeout_g))
     {
       char **tmp;
 
@@ -448,7 +448,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   char name[6 * DATA_MAX_NAME_LEN];
   cache_entry_t *ce = NULL;
   int send_okay_notification = 0;
-  time_t update_delay = 0;
+  cdtime_t update_delay = 0;
   notification_t n;
   int status;
   int i;
@@ -475,9 +475,11 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   if (ce->last_time >= vl->time)
   {
     pthread_mutex_unlock (&cache_lock);
-    NOTICE ("uc_update: Value too old: name = %s; value time = %u; "
-       "last cache update = %u;",
-       name, (unsigned int) vl->time, (unsigned int) ce->last_time);
+    NOTICE ("uc_update: Value too old: name = %s; value time = %.3f; "
+       "last cache update = %.3f;",
+       name,
+       CDTIME_T_TO_DOUBLE (vl->time),
+       CDTIME_T_TO_DOUBLE (ce->last_time));
     return (-1);
   }
 
@@ -487,7 +489,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   {
     send_okay_notification = 1;
     ce->state = STATE_OKAY;
-    update_delay = time (NULL) - ce->last_update;
+    update_delay = cdtime () - ce->last_update;
   }
 
   for (i = 0; i < ds->ds_num; i++)
@@ -514,7 +516,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
          }
 
          ce->values_gauge[i] = ((double) diff)
-           / ((double) (vl->time - ce->last_time));
+           / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
          ce->values_raw[i].counter = vl->values[i].counter;
        }
        break;
@@ -531,14 +533,14 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
          diff = vl->values[i].derive - ce->values_raw[i].derive;
 
          ce->values_gauge[i] = ((double) diff)
-           / ((double) (vl->time - ce->last_time));
+           / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
          ce->values_raw[i].derive = vl->values[i].derive;
        }
        break;
 
       case DS_TYPE_ABSOLUTE:
        ce->values_gauge[i] = ((double) vl->values[i].absolute)
-         / ((double) (vl->time - ce->last_time));
+         / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
        ce->values_raw[i].absolute = vl->values[i].absolute;
        break;
 
@@ -571,7 +573,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   uc_check_range (ds, ce);
 
   ce->last_time = vl->time;
-  ce->last_update = time (NULL);
+  ce->last_update = cdtime ();
   ce->interval = vl->interval;
 
   pthread_mutex_unlock (&cache_lock);
@@ -682,14 +684,14 @@ gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
   return (ret);
 } /* gauge_t *uc_get_rate */
 
-int uc_get_names (char ***ret_names, time_t **ret_times, size_t *ret_number)
+int uc_get_names (char ***ret_names, cdtime_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;
+  cdtime_t *times = NULL;
   size_t number = 0;
 
   int status = 0;
@@ -710,9 +712,9 @@ int uc_get_names (char ***ret_names, time_t **ret_times, size_t *ret_number)
 
     if (ret_times != NULL)
     {
-      time_t *tmp_times;
+      cdtime_t *tmp_times;
 
-      tmp_times = (time_t *) realloc (times, sizeof (time_t) * (number + 1));
+      tmp_times = (cdtime_t *) realloc (times, sizeof (cdtime_t) * (number + 1));
       if (tmp_times == NULL)
       {
        status = -1;
index f8059ec..87f93c0 100644 (file)
@@ -35,7 +35,7 @@ int uc_update (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);
 gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl);
 
-int uc_get_names (char ***ret_names, time_t **ret_times, size_t *ret_number);
+int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number);
 
 int uc_get_state (const data_set_t *ds, const value_list_t *vl);
 int uc_set_state (const data_set_t *ds, const value_list_t *vl, int state);
index 0e7b350..3584f3b 100644 (file)
@@ -54,7 +54,7 @@ int handle_flush (FILE *fh, char *buffer)
        int success = 0;
        int error   = 0;
 
-       int timeout = -1;
+       double timeout = 0.0;
        char **plugins = NULL;
        int plugins_num = 0;
        char **identifiers = NULL;
@@ -106,9 +106,9 @@ int handle_flush (FILE *fh, char *buffer)
                        
                        errno = 0;
                        endptr = NULL;
-                       timeout = strtol (opt_value, &endptr, 0);
+                       timeout = strtod (opt_value, &endptr);
 
-                       if ((endptr == opt_value) || (errno != 0))
+                       if ((endptr == opt_value) || (errno != 0) || (!isfinite (timeout)))
                        {
                                print_to_socket (fh, "-1 Invalid value for option `timeout': "
                                                "%s\n", opt_value);
@@ -116,8 +116,10 @@ int handle_flush (FILE *fh, char *buffer)
                                sfree (identifiers);
                                return (-1);
                        }
-                       else if (timeout <= 0)
-                               timeout = -1;
+                       else if (timeout < 0.0)
+                       {
+                               timeout = 0.0;
+                       }
                }
                else
                {
@@ -149,7 +151,9 @@ int handle_flush (FILE *fh, char *buffer)
                        int status;
 
                        identifier = identifiers[j];
-                       status = plugin_flush (plugin, timeout, identifier);
+                       status = plugin_flush (plugin,
+                                       DOUBLE_TO_CDTIME_T (timeout),
+                                       identifier);
                        if (status == 0)
                                success++;
                        else
index 4ca9646..ef66af5 100644 (file)
@@ -50,7 +50,7 @@ int handle_listval (FILE *fh, char *buffer)
 {
   char *command;
   char **names = NULL;
-  time_t *times = NULL;
+  cdtime_t *times = NULL;
   size_t number = 0;
   size_t i;
   int status;
@@ -90,7 +90,8 @@ int handle_listval (FILE *fh, char *buffer)
   print_to_socket (fh, "%i Value%s found\n",
       (int) number, (number == 1) ? "" : "s");
   for (i = 0; i < number; i++)
-    print_to_socket (fh, "%u %s\n", (unsigned int) times[i], names[i]);
+    print_to_socket (fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE (times[i]),
+               names[i]);
 
   free_everything_and_return (0);
 } /* int handle_listval */
index 15cd939..dd43337 100644 (file)
@@ -56,16 +56,16 @@ static int set_option (value_list_t *vl, const char *key, const char *value)
 
        if (strcasecmp ("interval", key) == 0)
        {
-               int tmp;
+               double tmp;
                char *endptr;
 
                endptr = NULL;
                errno = 0;
-               tmp = strtol (value, &endptr, 0);
+               tmp = strtod (value, &endptr);
 
                if ((errno == 0) && (endptr != NULL)
-                               && (endptr != value) && (tmp > 0))
-                       vl->interval = tmp;
+                               && (endptr != value) && (tmp > 0.0))
+                       vl->interval = DOUBLE_TO_CDTIME_T (tmp);
        }
        else
                return (1);
@@ -246,9 +246,11 @@ int create_putval (char *ret, size_t ret_len, /* {{{ */
        escape_string (buffer_values, sizeof (buffer_values));
 
        ssnprintf (ret, ret_len,
-                       "PUTVAL %s interval=%i %s",
+                       "PUTVAL %s interval=%.3f %s",
                        buffer_ident,
-                       (vl->interval > 0) ? vl->interval : interval_g,
+                       (vl->interval > 0)
+                       ? CDTIME_T_TO_DOUBLE (vl->interval)
+                       : CDTIME_T_TO_DOUBLE (interval_g),
                        buffer_values);
 
        return (0);
index 78c8052..dcac807 100644 (file)
@@ -73,7 +73,7 @@ struct udb_query_preparation_area_s /* {{{ */
   char *plugin;
   char *db_name;
 
-  int interval;
+  cdtime_t interval;
 
   udb_result_preparation_area_t *result_prep_areas;
 }; /* }}} */
@@ -839,7 +839,7 @@ void udb_query_finish_result (const udb_query_t const *q, /* {{{ */
   sfree (prep_area->plugin);
   sfree (prep_area->db_name);
 
-  prep_area->interval = -1;
+  prep_area->interval = 0;
 
   for (r = q->results, r_area = prep_area->result_prep_areas;
       r != NULL; r = r->next, r_area = r_area->next)
@@ -907,7 +907,7 @@ int udb_query_handle_result (const udb_query_t const *q, /* {{{ */
 int udb_query_prepare_result (const udb_query_t const *q, /* {{{ */
     udb_query_preparation_area_t *prep_area,
     const char *host, const char *plugin, const char *db_name,
-    char **column_names, size_t column_num, int interval)
+    char **column_names, size_t column_num, cdtime_t interval)
 {
   udb_result_preparation_area_t *r_area;
   udb_result_t *r;
index 846f81c..727be03 100644 (file)
@@ -68,7 +68,7 @@ int udb_query_check_version (udb_query_t *q, unsigned int version);
 int udb_query_prepare_result (const udb_query_t const *q,
     udb_query_preparation_area_t *prep_area,
     const char *host, const char *plugin, const char *db_name,
-    char **column_names, size_t column_num, int interval);
+    char **column_names, size_t column_num, cdtime_t interval);
 int udb_query_handle_result (const udb_query_t const *q,
     udb_query_preparation_area_t *prep_area, char **column_values);
 void udb_query_finish_result (const udb_query_t const *q,
index ac88c0f..65c886b 100644 (file)
@@ -265,7 +265,7 @@ static int value_list_to_json (char *buffer, size_t buffer_size, /* {{{ */
   BUFFER_ADD (",\"dsnames\":%s", temp);
 
   BUFFER_ADD (",\"time\":%lu", (unsigned long) vl->time);
-  BUFFER_ADD (",\"interval\":%i", vl->interval);
+  BUFFER_ADD (",\"interval\":%.3f", CDTIME_T_TO_DOUBLE (vl->interval));
 
 #define BUFFER_ADD_KEYVAL(key, value) do { \
   status = escape_string (temp, sizeof (temp), (value)); \
index 4ecec59..7a389f2 100644 (file)
@@ -103,7 +103,10 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
     return (-1);
   }
 
-  ss = (cfg->stepsize > 0) ? cfg->stepsize : vl->interval;
+  if (cfg->stepsize > 0)
+    ss = cfg->stepsize;
+  else
+    ss = (int) CDTIME_T_TO_TIME_T (vl->interval);
   if (ss <= 0)
   {
     *ret = NULL;
@@ -241,7 +244,9 @@ static int ds_get (char ***ret, /* {{{ */
     status = ssnprintf (buffer, sizeof (buffer),
         "DS:%s:%s:%i:%s:%s",
         d->name, type,
-        (cfg->heartbeat > 0) ? cfg->heartbeat : (2 * vl->interval),
+        (cfg->heartbeat > 0)
+        ? cfg->heartbeat
+        : (int) CDTIME_T_TO_TIME_T (2 * vl->interval),
         min, max);
     if ((status < 1) || ((size_t) status >= sizeof (buffer)))
       break;
@@ -323,7 +328,7 @@ static int srrd_create (const char *filename, /* {{{ */
     last_up = time (NULL) - 10;
 
   ssnprintf (pdp_step_str, sizeof (pdp_step_str), "%lu", pdp_step);
-  ssnprintf (last_up_str, sizeof (last_up_str), "%u", (unsigned int) last_up);
+  ssnprintf (last_up_str, sizeof (last_up_str), "%lu", (unsigned long) last_up);
 
   new_argv[0] = "create";
   new_argv[1] = (void *) filename;
@@ -368,6 +373,8 @@ int cu_rrd_create_file (const char *filename, /* {{{ */
   char **ds_def;
   int ds_num;
   int status = 0;
+  time_t last_up;
+  int stepsize;
 
   if (check_create_dir (filename))
     return (-1);
@@ -398,10 +405,19 @@ int cu_rrd_create_file (const char *filename, /* {{{ */
   memcpy (argv + ds_num, rra_def, rra_num * sizeof (char *));
   argv[ds_num + rra_num] = NULL;
 
+  if (vl->time == 0)
+    last_up = time (NULL) - 10;
+  else
+    last_up = CDTIME_T_TO_TIME_T (vl->time) - 10;
+
+  if (cfg->stepsize > 0)
+    stepsize = cfg->stepsize;
+  else
+    stepsize = (int) CDTIME_T_TO_TIME_T (vl->interval);
+
   assert (vl->time > 10);
   status = srrd_create (filename,
-      (cfg->stepsize > 0) ? cfg->stepsize : vl->interval,
-      vl->time - 10,
+      stepsize, last_up,
       argc, (const char **) argv);
 
   free (argv);
diff --git a/src/utils_time.c b/src/utils_time.c
new file mode 100644 (file)
index 0000000..420b425
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * collectd - src/utils_time.h
+ * Copyright (C) 2010  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
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <ff at octo.it>
+ **/
+
+#include "collectd.h"
+#include "utils_time.h"
+#include "plugin.h"
+#include "common.h"
+
+cdtime_t cdtime (void) /* {{{ */
+{
+  int status;
+  struct timespec ts = { 0, 0 };
+
+  status = clock_gettime (CLOCK_REALTIME, &ts);
+  if (status != 0)
+  {
+    char errbuf[1024];
+    ERROR ("cdtime: clock_gettime failed: %s",
+        sstrerror (errno, errbuf, sizeof (errbuf)));
+    return (0);
+  }
+
+  return (TIMESPEC_TO_CDTIME_T (&ts));
+} /* }}} cdtime_t cdtime */
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
diff --git a/src/utils_time.h b/src/utils_time.h
new file mode 100644 (file)
index 0000000..da73492
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * collectd - src/utils_time.h
+ * Copyright (C) 2010  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
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <ff at octo.it>
+ **/
+
+#ifndef UTILS_TIME_H
+#define UTILS_TIME_H 1
+
+#include "collectd.h"
+
+/*
+ * "cdtime_t" is a 64bit unsigned integer. The time is stored at a 2^-30 second
+ * resolution, i.e. the most significant 34 bit are used to store the time in
+ * seconds, the least significant bits store the sub-second part in something
+ * very close to nanoseconds. *The* big advantage of storing time in this
+ * manner is that comparing times and calculating differences is as simple as
+ * it is with "time_t", i.e. a simple integer comparison / subtraction works.
+ */
+/* 
+ * cdtime_t is defined in "collectd.h" */
+/* typedef uint64_t cdtime_t; */
+
+/* 2^30 = 1073741824 */
+#define TIME_T_TO_CDTIME_T(t) (((cdtime_t) (t)) * 1073741824)
+#define CDTIME_T_TO_TIME_T(t) ((time_t) ((t) / 1073741824))
+
+#define CDTIME_T_TO_DOUBLE(t) (((double) (t)) / 1073741824.0)
+#define DOUBLE_TO_CDTIME_T(d) ((cdtime_t) ((d) * 1073741824.0))
+
+#define MS_TO_CDTIME_T(ms) ((cdtime_t)    (((double) (ms)) * 1073741.824))
+#define CDTIME_T_TO_MS(t)  ((long)        (((double) (t))  / 1073741.824))
+#define US_TO_CDTIME_T(us) ((cdtime_t)    (((double) (us)) * 1073.741824))
+#define CDTIME_T_TO_US(t)  ((suseconds_t) (((double) (t))  / 1073.741824))
+#define NS_TO_CDTIME_T(ns) ((cdtime_t)    (((double) (ns)) * 1.073741824))
+#define CDTIME_T_TO_NS(t)  ((long)        (((double) (t))  / 1.073741824))
+
+#define CDTIME_T_TO_TIMEVAL(cdt,tvp) do {                                    \
+        (tvp)->tv_sec = CDTIME_T_TO_TIME_T (cdt);                            \
+        (tvp)->tv_usec = CDTIME_T_TO_US ((cdt) % 1073741824);                \
+} while (0)
+#define TIMEVAL_TO_CDTIME_T(tv) (TIME_T_TO_CDTIME_T ((tv).tv_sec)            \
+    + US_TO_CDTIME_T ((tv).tv_usec))
+
+#define CDTIME_T_TO_TIMESPEC(cdt,tsp) do {                                   \
+  (tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt);                                  \
+  (tsp)->tv_nsec = CDTIME_T_TO_NS ((cdt) % 1073741824);                      \
+} while (0)
+#define TIMESPEC_TO_CDTIME_T(ts) (TIME_T_TO_CDTIME_T ((ts)->tv_sec)           \
+    + NS_TO_CDTIME_T ((ts)->tv_nsec))
+
+cdtime_t cdtime (void);
+
+#endif /* UTILS_TIME_H */
+/* vim: set sw=2 sts=2 et : */
index bac8e98..1a0e4ef 100644 (file)
@@ -61,7 +61,7 @@ struct wh_callback_s
         char   send_buffer[4096];
         size_t send_buffer_free;
         size_t send_buffer_fill;
-        time_t send_buffer_init_time;
+        cdtime_t send_buffer_init_time;
 
         pthread_mutex_t send_lock;
 };
@@ -72,7 +72,7 @@ static void wh_reset_buffer (wh_callback_t *cb)  /* {{{ */
         memset (cb->send_buffer, 0, sizeof (cb->send_buffer));
         cb->send_buffer_free = sizeof (cb->send_buffer);
         cb->send_buffer_fill = 0;
-        cb->send_buffer_init_time = time (NULL);
+        cb->send_buffer_init_time = cdtime ();
 
         if (cb->format == WH_FORMAT_JSON)
         {
@@ -157,19 +157,21 @@ static int wh_callback_init (wh_callback_t *cb) /* {{{ */
         return (0);
 } /* }}} int wh_callback_init */
 
-static int wh_flush_nolock (int timeout, wh_callback_t *cb) /* {{{ */
+static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */
 {
         int status;
 
-        DEBUG ("write_http plugin: wh_flush_nolock: timeout = %i; "
+        DEBUG ("write_http plugin: wh_flush_nolock: timeout = %.3f; "
                         "send_buffer_fill = %zu;",
-                        timeout, cb->send_buffer_fill);
+                        CDTIME_T_TO_DOUBLE (timeout),
+                        cb->send_buffer_fill);
 
+        /* timeout == 0  => flush unconditionally */
         if (timeout > 0)
         {
-                time_t now;
+                cdtime_t now;
 
-                now = time (NULL);
+                now = cdtime ();
                 if ((cb->send_buffer_init_time + timeout) > now)
                         return (0);
         }
@@ -178,7 +180,7 @@ static int wh_flush_nolock (int timeout, wh_callback_t *cb) /* {{{ */
         {
                 if (cb->send_buffer_fill <= 0)
                 {
-                        cb->send_buffer_init_time = time (NULL);
+                        cb->send_buffer_init_time = cdtime ();
                         return (0);
                 }
 
@@ -189,7 +191,7 @@ static int wh_flush_nolock (int timeout, wh_callback_t *cb) /* {{{ */
         {
                 if (cb->send_buffer_fill <= 2)
                 {
-                        cb->send_buffer_init_time = time (NULL);
+                        cb->send_buffer_init_time = cdtime ();
                         return (0);
                 }
 
@@ -218,7 +220,7 @@ static int wh_flush_nolock (int timeout, wh_callback_t *cb) /* {{{ */
         return (status);
 } /* }}} wh_flush_nolock */
 
-static int wh_flush (int timeout, /* {{{ */
+static int wh_flush (cdtime_t timeout, /* {{{ */
                 const char *identifier __attribute__((unused)),
                 user_data_t *user_data)
 {
@@ -258,7 +260,7 @@ static void wh_callback_free (void *data) /* {{{ */
 
         cb = data;
 
-        wh_flush_nolock (/* timeout = */ -1, cb);
+        wh_flush_nolock (/* timeout = */ 0, cb);
 
         curl_easy_cleanup (cb->curl);
         sfree (cb->location);
@@ -304,8 +306,10 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{
         }
 
         command_len = (size_t) ssnprintf (command, sizeof (command),
-                        "PUTVAL %s interval=%i %s\r\n",
-                        key, vl->interval, values);
+                        "PUTVAL %s interval=%.3f %s\r\n",
+                        key,
+                        CDTIME_T_TO_DOUBLE (vl->interval),
+                        values);
         if (command_len >= sizeof (command)) {
                 ERROR ("write_http plugin: Command buffer too small: "
                                 "Need %zu bytes.", command_len + 1);
@@ -327,7 +331,7 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{
 
         if (command_len >= cb->send_buffer_free)
         {
-                status = wh_flush_nolock (/* timeout = */ -1, cb);
+                status = wh_flush_nolock (/* timeout = */ 0, cb);
                 if (status != 0)
                 {
                         pthread_mutex_unlock (&cb->send_lock);
@@ -379,7 +383,7 @@ static int wh_write_json (const data_set_t *ds, const value_list_t *vl, /* {{{ *
                         ds, vl, cb->store_rates);
         if (status == (-ENOMEM))
         {
-                status = wh_flush_nolock (/* timeout = */ -1, cb);
+                status = wh_flush_nolock (/* timeout = */ 0, cb);
                 if (status != 0)
                 {
                         wh_reset_buffer (cb);