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

1  2 
configure.in
src/Makefile.am
src/collectd.h
src/netapp.c
src/network.c
src/notify_email.c
src/python.c
src/utils_cache.c

diff --combined configure.in
@@@ -91,10 -91,6 +91,10 @@@ if test "x$ac_system" = "xSolaris
  then
        AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Define to enforce POSIX thread semantics under Solaris.])
  fi
 +if test "x$ac_system" = "xAIX"
 +then
 +      AC_DEFINE(_THREAD_SAFE_ERRNO, 1, [Define to use the thread-safe version of errno under AIX.])
 +fi
  
  # Where to install .pc files.
  pkgconfigdir="${libdir}/pkgconfig"
@@@ -572,6 -568,16 +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,
          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"])
  if test "x$with_perfstat" = "xyes"
  then
         AC_DEFINE(HAVE_PERFSTAT, 1, [Define to 1 if you have the 'perfstat' library (-lperfstat)])
 +       # struct members pertaining to donation have been added to libperfstat somewhere between AIX5.3ML5 and AIX5.3ML9
 +       AC_CHECK_MEMBER([perfstat_partition_type_t.b.donate_enabled], [], [], [[#include <libperfstat.h]])
 +       if test "x$av_cv_member_perfstat_partition_type_t_b_donate_enabled" = "xyes"
 +       then
 +              AC_DEFINE(PERFSTAT_SUPPORTS_DONATION, 1, [Define to 1 if your version of the 'perfstat' library supports donation])
 +       fi
  fi
  AM_CONDITIONAL(BUILD_WITH_PERFSTAT, test "x$with_perfstat" = "xyes")
  
  fi
  # }}} --with-python
  
 +# --with-librabbitmq {{{
 +with_librabbitmq_cppflags=""
 +with_librabbitmq_ldflags=""
 +AC_ARG_WITH(librabbitmq, [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])],
 +[
 +      if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +      then
 +              with_librabbitmq_cppflags="-I$withval/include"
 +              with_librabbitmq_ldflags="-L$withval/lib"
 +              with_librabbitmq="yes"
 +      else
 +              with_librabbitmq="$withval"
 +      fi
 +],
 +[
 +      with_librabbitmq="yes"
 +])
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
 +
 +      AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      SAVE_LDFLAGS="$LDFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
 +      LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
 +
 +      AC_CHECK_LIB(rabbitmq, amqp_basic_publish, [with_librabbitmq="yes"], [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +      LDFLAGS="$SAVE_LDFLAGS"
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      BUILD_WITH_LIBRABBITMQ_CPPFLAGS="$with_librabbitmq_cppflags"
 +      BUILD_WITH_LIBRABBITMQ_LDFLAGS="$with_librabbitmq_ldflags"
 +      BUILD_WITH_LIBRABBITMQ_LIBS="-lrabbitmq"
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS)
 +      AC_DEFINE(HAVE_LIBRABBITMQ, 1, [Define if librabbitmq is present and usable.])
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes")
 +# }}}
 +
  # --with-librouteros {{{
  AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])],
  [
@@@ -4523,7 -4473,6 +4534,7 @@@ AC_ARG_ENABLE([all-plugins]
  
  m4_divert_once([HELP_ENABLE], [])
  
 +AC_PLUGIN([amqp],        [$with_librabbitmq],  [AMQP output plugin])
  AC_PLUGIN([apache],      [$with_libcurl],      [Apache httpd statistics])
  AC_PLUGIN([apcups],      [yes],                [Statistics of UPSes by APC])
  AC_PLUGIN([apple_sensors], [$with_libiokit],   [Apple's hardware sensors])
@@@ -4558,7 -4507,6 +4569,7 @@@ AC_PLUGIN([java],        [$with_java]
  AC_PLUGIN([libvirt],     [$plugin_libvirt],    [Virtual machine statistics])
  AC_PLUGIN([load],        [$plugin_load],       [System load])
  AC_PLUGIN([logfile],     [yes],                [File logging plugin])
 +AC_PLUGIN([lpar],        [$with_perfstat],     [AIX logical partitions statistics])
  AC_PLUGIN([madwifi],     [$have_linux_wireless_h], [Madwifi wireless statistics])
  AC_PLUGIN([match_empty_counter], [yes],        [The empty counter match])
  AC_PLUGIN([match_hashed], [yes],               [The hashed match])
@@@ -4824,7 -4772,6 +4835,7 @@@ Configuration
      libperl . . . . . . . $with_libperl
      libpq . . . . . . . . $with_libpq
      libpthread  . . . . . $with_libpthread
 +    librabbitmq . . . . . $with_librabbitmq
      librouteros . . . . . $with_librouteros
      librrd  . . . . . . . $with_librrd
      libsensors  . . . . . $with_libsensors
      perl  . . . . . . . . $with_perl_bindings
  
    Modules:
 +    amqp    . . . . . . . $enable_amqp
      apache  . . . . . . . $enable_apache
      apcups  . . . . . . . $enable_apcups
      apple_sensors . . . . $enable_apple_sensors
      libvirt . . . . . . . $enable_libvirt
      load  . . . . . . . . $enable_load
      logfile . . . . . . . $enable_logfile
 +    lpar... . . . . . . . $enable_lpar
      madwifi . . . . . . . $enable_madwifi
      match_empty_counter . $enable_match_empty_counter
      match_hashed  . . . . $enable_match_hashed
diff --combined src/Makefile.am
@@@ -41,6 -41,7 +41,7 @@@ collectd_SOURCES = collectd.c collectd.
                   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)
@@@ -123,18 -124,6 +124,18 @@@ pkglib_LTLIBRARIES 
  BUILT_SOURCES = 
  CLEANFILES = 
  
 +if BUILD_PLUGIN_AMQP
 +pkglib_LTLIBRARIES += amqp.la
 +amqp_la_SOURCES = amqp.c \
 +                utils_cmd_putval.c utils_cmd_putval.h \
 +                utils_format_json.c utils_format_json.h
 +amqp_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
 +amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
 +amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS)
 +collectd_LDADD += "-dlopen" amqp.la
 +collectd_DEPENDENCIES += amqp.la
 +endif
 +
  if BUILD_PLUGIN_APACHE
  pkglib_LTLIBRARIES += apache.la
  apache_la_SOURCES = apache.c
@@@ -524,15 -513,6 +525,15 @@@ collectd_LDADD += "-dlopen" logfile.l
  collectd_DEPENDENCIES += logfile.la
  endif
  
 +if BUILD_PLUGIN_LPAR
 +pkglib_LTLIBRARIES += lpar.la
 +lpar_la_SOURCES = lpar.c
 +lpar_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" lpar.la
 +collectd_DEPENDENCIES += lpar.la
 +lpar_la_LIBADD = -lperfstat
 +endif
 +
  if BUILD_PLUGIN_MADWIFI
  pkglib_LTLIBRARIES += madwifi.la
  madwifi_la_SOURCES = madwifi.c madwifi.h
diff --combined src/collectd.h
  # include <kstat.h>
  #endif
  
 -#if HAVE_SENSORS_SENSORS_H
 -# include <sensors/sensors.h>
 -#endif
 -
  #ifndef PACKAGE_NAME
  #define PACKAGE_NAME "collectd"
  #endif
  # 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 */
diff --combined src/netapp.c
@@@ -38,8 -38,8 +38,8 @@@ typedef void service_handler_t(host_con
  
  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 +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;
  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 +153,7 @@@ typedef struct data_volume_perf_s data_
  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 +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 +566,7 @@@ static int submit_values (const char *h
                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 timestamp, cdtime_t interval)
  {
        value_list_t vl = VALUE_LIST_INIT;
  
        if (timestamp > 0)
                vl.time = timestamp;
  
 +      if (interval > 0)
 +              vl.interval = interval;
 +
        if (host != NULL)
                sstrncpy (vl.host, host, sizeof (vl.host));
        else
  
  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 timestamp, cdtime_t interval)
  {
        value_t values[2];
  
        values[1].counter = val1;
  
        return (submit_values (host, plugin_inst, type, type_inst,
 -                              values, 2, timestamp));
 +                              values, 2, timestamp, interval));
  } /* }}} 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)
++              const char *type, const char *type_inst, counter_t counter,
++              cdtime_t timestamp, cdtime_t interval)
  {
        value_t v;
  
        v.counter = counter;
  
        return (submit_values (host, plugin_inst, type, type_inst,
 -                              &v, 1, timestamp));
 +                              &v, 1, timestamp, interval));
  } /* }}} int submit_counter */
  
  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 timestamp, cdtime_t interval)
  {
        value_t values[2];
  
        values[1].gauge = val1;
  
        return (submit_values (host, plugin_inst, type, type_inst,
 -                              values, 2, timestamp));
 +                              values, 2, timestamp, interval));
  } /* }}} 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)
++              const char *type, const char *type_inst, double d,
++              cdtime_t timestamp, cdtime_t interval)
  {
        value_t v;
  
        v.gauge = (gauge_t) d;
  
        return (submit_values (host, plugin_inst, type, type_inst,
 -                              &v, 1, timestamp));
 +                              &v, 1, timestamp, interval));
  } /* }}} int submit_uint64 */
  
  /* Calculate hit ratio from old and new counters and submit the resulting
@@@ -650,8 -647,7 +652,8 @@@ static int submit_cache_ratio (const ch
                uint64_t new_misses,
                uint64_t old_hits,
                uint64_t old_misses,
-               time_t timestamp,
-               int interval)
 -              cdtime_t timestamp)
++              cdtime_t timestamp,
++              cdtime_t interval)
  {
        value_t v;
  
        }
  
        return (submit_values (host, plugin_inst, "cache_ratio", type_inst,
 -                              &v, 1, timestamp));
 +                              &v, 1, timestamp, interval));
  } /* }}} int submit_cache_ratio */
  
  /* Submits all the caches used by WAFL. Uses "submit_cache_ratio". */
  static int submit_wafl_data (const char *hostname, const char *instance, /* {{{ */
 -              cfg_wafl_t *old_data, const cfg_wafl_t *new_data)
 +              cfg_wafl_t *old_data, const cfg_wafl_t *new_data, int interval)
  {
        /* Submit requested counters */
        if (HAS_ALL_FLAGS (old_data->flags, CFG_WAFL_NAME_CACHE | HAVE_WAFL_NAME_CACHE)
                submit_cache_ratio (hostname, instance, "name_cache_hit",
                                new_data->name_cache_hit, new_data->name_cache_miss,
                                old_data->name_cache_hit, old_data->name_cache_miss,
 -                              new_data->timestamp);
 +                              new_data->timestamp, interval);
  
        if (HAS_ALL_FLAGS (old_data->flags, CFG_WAFL_DIR_CACHE | HAVE_WAFL_FIND_DIR)
                        && HAS_ALL_FLAGS (new_data->flags, HAVE_WAFL_FIND_DIR))
                submit_cache_ratio (hostname, instance, "find_dir_hit",
                                new_data->find_dir_hit, new_data->find_dir_miss,
                                old_data->find_dir_hit, old_data->find_dir_miss,
 -                              new_data->timestamp);
 +                              new_data->timestamp, interval);
  
        if (HAS_ALL_FLAGS (old_data->flags, CFG_WAFL_BUF_CACHE | HAVE_WAFL_BUF_HASH)
                        && HAS_ALL_FLAGS (new_data->flags, HAVE_WAFL_BUF_HASH))
                submit_cache_ratio (hostname, instance, "buf_hash_hit",
                                new_data->buf_hash_hit, new_data->buf_hash_miss,
                                old_data->buf_hash_hit, old_data->buf_hash_miss,
 -                              new_data->timestamp);
 +                              new_data->timestamp, interval);
  
        if (HAS_ALL_FLAGS (old_data->flags, CFG_WAFL_INODE_CACHE | HAVE_WAFL_INODE_CACHE)
                        && HAS_ALL_FLAGS (new_data->flags, HAVE_WAFL_INODE_CACHE))
                submit_cache_ratio (hostname, instance, "inode_cache_hit",
                                new_data->inode_cache_hit, new_data->inode_cache_miss,
                                old_data->inode_cache_hit, old_data->inode_cache_miss,
 -                              new_data->timestamp);
 +                              new_data->timestamp, interval);
  
        /* Clear old HAVE_* flags */
        old_data->flags &= ~HAVE_WAFL_ALL;
   * update flags appropriately. */
  static int submit_volume_perf_data (const char *hostname, /* {{{ */
                data_volume_perf_t *old_data,
 -              const data_volume_perf_t *new_data)
 +              const data_volume_perf_t *new_data, int interval)
  {
        char plugin_instance[DATA_MAX_NAME_LEN];
  
                        && HAS_ALL_FLAGS (new_data->flags, HAVE_VOLUME_PERF_BYTES_READ | HAVE_VOLUME_PERF_BYTES_WRITE))
        {
                submit_two_counters (hostname, plugin_instance, "disk_octets", /* type instance = */ NULL,
 -                              (counter_t) new_data->read_bytes, (counter_t) new_data->write_bytes, new_data->timestamp);
 +                              (counter_t) new_data->read_bytes, (counter_t) new_data->write_bytes, new_data->timestamp, interval);
        }
  
        /* Check for and submit disk-operations values */
                        && HAS_ALL_FLAGS (new_data->flags, HAVE_VOLUME_PERF_OPS_READ | HAVE_VOLUME_PERF_OPS_WRITE))
        {
                submit_two_counters (hostname, plugin_instance, "disk_ops", /* type instance = */ NULL,
 -                              (counter_t) new_data->read_ops, (counter_t) new_data->write_ops, new_data->timestamp);
 +                              (counter_t) new_data->read_ops, (counter_t) new_data->write_ops, new_data->timestamp, interval);
        }
  
        /* Check for, calculate and submit disk-latency values */
                }
  
                submit_two_gauge (hostname, plugin_instance, "disk_latency", /* type instance = */ NULL,
 -                              latency_per_op_read, latency_per_op_write, new_data->timestamp);
 +                              latency_per_op_read, latency_per_op_write, new_data->timestamp, interval);
        }
  
        /* Clear all HAVE_* flags. */
        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
   *
   */
  /* Data corresponding to <WAFL /> */
  static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /* {{{ */
 -              na_elem_t *data)
 +              na_elem_t *data, int interval)
  {
        cfg_wafl_t perf_data;
        const char *plugin_inst;
  
        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)
                }
        }
  
 -      return (submit_wafl_data (hostname, plugin_inst, cfg_wafl, &perf_data));
 +      return (submit_wafl_data (hostname, plugin_inst, cfg_wafl, &perf_data, interval));
  } /* }}} void cna_handle_wafl_data */
  
  static int cna_setup_wafl (cfg_wafl_t *cw) /* {{{ */
@@@ -950,7 -956,7 +962,7 @@@ static int cna_query_wafl (host_config_
  {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
  
        if (host == NULL)
                return (EINVAL);
        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);
  
                return (-1);
        }
  
 -      status = cna_handle_wafl_data (host->name, host->cfg_wafl, data);
 +      status = cna_handle_wafl_data (host->name, host->cfg_wafl, data, host->interval);
  
        if (status == 0)
                host->cfg_wafl->interval.last_read = now;
  
  /* 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)
++              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;
        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)
  
        if ((cfg_disk->flags & CFG_DISK_BUSIEST) && (worst_disk != NULL))
                submit_double (hostname, "system", "percent", "disk_busy",
 -                              worst_disk->disk_busy_percent, timestamp);
 +                              worst_disk->disk_busy_percent, timestamp, interval);
  
        return (0);
  } /* }}} int cna_handle_disk_data */
@@@ -1144,7 -1150,7 +1156,7 @@@ static int cna_query_disk (host_config_
  {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
  
        if (host == NULL)
                return (EINVAL);
        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);
  
                return (-1);
        }
  
 -      status = cna_handle_disk_data (host->name, host->cfg_disk, data);
 +      status = cna_handle_disk_data (host->name, host->cfg_disk, data, host->interval);
  
        if (status == 0)
                host->cfg_disk->interval.last_read = now;
  
  /* 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)
++              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)
                        }
                } /* for (elem_counter) */
  
 -              submit_volume_perf_data (hostname, v, &perf_data);
 +              submit_volume_perf_data (hostname, v, &perf_data, interval);
        } /* for (volume) */
  
        return (0);
@@@ -1315,7 -1321,7 +1327,7 @@@ static int cna_query_volume_perf (host_
  {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
  
        if (host == NULL)
                return (EINVAL);
        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);
  
                return (-1);
        }
  
 -      status = cna_handle_volume_perf_data (host->name, host->cfg_volume_perf, data);
 +      status = cna_handle_volume_perf_data (host->name, host->cfg_volume_perf, data, host->interval);
  
        if (status == 0)
                host->cfg_volume_perf->interval.last_read = now;
  
  /* Data corresponding to <VolumeUsage /> */
  static int cna_submit_volume_usage_data (const char *hostname, /* {{{ */
 -              cfg_volume_usage_t *cfg_volume)
 +              cfg_volume_usage_t *cfg_volume, int interval)
  {
        data_volume_usage_t *v;
  
                if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_NORM_FREE))
                        submit_double (hostname, /* plugin instance = */ plugin_instance,
                                        "df_complex", "free",
 -                                      (double) norm_free, /* timestamp = */ 0);
 +                                      (double) norm_free, /* timestamp = */ 0, interval);
  
                if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_SIS_SAVED))
                        submit_double (hostname, /* plugin instance = */ plugin_instance,
                                        "df_complex", "sis_saved",
 -                                      (double) sis_saved, /* timestamp = */ 0);
 +                                      (double) sis_saved, /* timestamp = */ 0, interval);
  
                if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_NORM_USED))
                        submit_double (hostname, /* plugin instance = */ plugin_instance,
                                        "df_complex", "used",
 -                                      (double) norm_used, /* timestamp = */ 0);
 +                                      (double) norm_used, /* timestamp = */ 0, interval);
  
                if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_SNAP_RSVD))
                        submit_double (hostname, /* plugin instance = */ plugin_instance,
                                        "df_complex", "snap_reserved",
 -                                      (double) snap_reserve_free, /* timestamp = */ 0);
 +                                      (double) snap_reserve_free, /* timestamp = */ 0, interval);
  
                if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_SNAP_USED | HAVE_VOLUME_USAGE_SNAP_RSVD))
                        submit_double (hostname, /* plugin instance = */ plugin_instance,
                                        "df_complex", "snap_reserve_used",
 -                                      (double) snap_reserve_used, /* timestamp = */ 0);
 +                                      (double) snap_reserve_used, /* timestamp = */ 0, interval);
  
                if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_SNAP_USED))
                        submit_double (hostname, /* plugin instance = */ plugin_instance,
                                        "df_complex", "snap_normal_used",
 -                                      (double) snap_norm_used, /* timestamp = */ 0);
 +                                      (double) snap_norm_used, /* timestamp = */ 0, interval);
  
                /* Clear all the HAVE_* flags */
                v->flags &= ~HAVE_VOLUME_USAGE_ALL;
@@@ -1444,7 -1450,7 +1456,7 @@@ static int cna_change_volume_status (co
        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));
@@@ -1654,7 -1660,7 +1666,7 @@@ static int cna_handle_volume_usage_dat
                } /* }}} end of 32-bit workaround */
        } /* for (elem_volume) */
  
 -      return (cna_submit_volume_usage_data (host->name, cfg_volume));
 +      return (cna_submit_volume_usage_data (host->name, cfg_volume, host->interval));
  } /* }}} int cna_handle_volume_usage_data */
  
  static int cna_setup_volume_usage (cfg_volume_usage_t *cvu) /* {{{ */
@@@ -1679,7 -1685,7 +1691,7 @@@ static int cna_query_volume_usage (host
  {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
  
        if (host == NULL)
                return (EINVAL);
        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);
  
  
  /* Data corresponding to <System /> */
  static int cna_handle_system_data (const char *hostname, /* {{{ */
 -              cfg_system_t *cfg_system, na_elem_t *data)
 +              cfg_system_t *cfg_system, na_elem_t *data, int interval)
  {
        na_elem_t *instances;
        na_elem_t *counter;
        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)
                                && (value > 0) && (strlen(name) > 4)
                                && (!strcmp(name + strlen(name) - 4, "_ops"))) {
                        submit_counter (hostname, instance, "disk_ops_complex", name,
 -                                      (counter_t) value, timestamp);
 +                                      (counter_t) value, timestamp, interval);
                }
        } /* for (counter) */
  
        if ((cfg_system->flags & CFG_SYSTEM_DISK)
                        && (HAS_ALL_FLAGS (counter_flags, 0x01 | 0x02)))
                submit_two_counters (hostname, instance, "disk_octets", NULL,
 -                              disk_read, disk_written, timestamp);
 +                              disk_read, disk_written, timestamp, interval);
                                
        if ((cfg_system->flags & CFG_SYSTEM_NET)
                        && (HAS_ALL_FLAGS (counter_flags, 0x04 | 0x08)))
                submit_two_counters (hostname, instance, "if_octets", NULL,
 -                              net_recv, net_sent, timestamp);
 +                              net_recv, net_sent, timestamp, interval);
  
        if ((cfg_system->flags & CFG_SYSTEM_CPU)
                        && (HAS_ALL_FLAGS (counter_flags, 0x10 | 0x20)))
        {
                submit_counter (hostname, instance, "cpu", "system",
 -                              cpu_busy, timestamp);
 +                              cpu_busy, timestamp, interval);
                submit_counter (hostname, instance, "cpu", "idle",
 -                              cpu_total - cpu_busy, timestamp);
 +                              cpu_total - cpu_busy, timestamp, interval);
        }
  
        return (0);
@@@ -1839,7 -1845,7 +1851,7 @@@ static int cna_query_system (host_confi
  {
        na_elem_t *data;
        int status;
-       time_t now;
+       cdtime_t now;
  
        if (host == NULL)
                return (EINVAL);
        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);
  
                return (-1);
        }
  
 -      status = cna_handle_system_data (host->name, host->cfg_system, data);
 +      status = cna_handle_system_data (host->name, host->cfg_system, data, host->interval);
  
        if (status == 0)
                host->cfg_system->interval.last_read = now;
@@@ -1905,23 -1911,12 +1917,12 @@@ static int cna_config_bool_to_flag (con
  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 -2416,7 +2422,7 @@@ static host_config_t *cna_config_host (
                } 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 -2547,7 +2553,7 @@@ static int cna_config (oconfig_item_t *
  
                        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;
diff --combined src/network.c
@@@ -31,7 -31,6 +31,7 @@@
  #include "utils_fbhash.h"
  #include "utils_avltree.h"
  #include "utils_cache.h"
 +#include "utils_complain.h"
  
  #include "network.h"
  
@@@ -918,8 -917,6 +918,8 @@@ static int parse_packet (sockent_t *se
  static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
      void **ret_buffer, size_t *ret_buffer_len, int flags)
  {
 +  static c_complain_t complain_no_users = C_COMPLAIN_INIT_STATIC;
 +
    char *buffer;
    size_t buffer_len;
    size_t buffer_offset;
  
    if (se->data.server.userdb == NULL)
    {
 -    NOTICE ("network plugin: Received signed network packet but can't verify "
 -        "it because no user DB has been configured. Will accept it.");
 +    c_complain (LOG_NOTICE, &complain_no_users,
 +        "network plugin: Received signed network packet but can't verify it "
 +        "because no user DB has been configured. Will accept it.");
      return (0);
    }
  
@@@ -1381,8 -1377,19 +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)
                        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 -2602,7 +2606,7 @@@ static int add_to_buffer (char *buffer
  
        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;
  
        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 -3092,7 +3096,7 @@@ static int network_notification (const 
  
    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 -3366,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);
  
diff --combined src/notify_email.c
@@@ -1,7 -1,6 +1,7 @@@
  /**
   * collectd - src/notify_email.c
   * Copyright (C) 2008  Oleg King
 + * Copyright (C) 2010  Florian 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
@@@ -19,7 -18,6 +19,7 @@@
   *
   * Authors:
   *   Oleg King <king2 at kaluga.ru>
 + *   Florian Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -28,7 -26,6 +28,7 @@@
  
  #include <auth-client.h>
  #include <libesmtp.h>
 +#include <pthread.h>
  
  #define MAXSTRING               256
  
@@@ -48,7 -45,6 +48,7 @@@ static char **recipients
  static int recipients_len = 0;
  
  static smtp_session_t session;
 +static pthread_mutex_t session_lock = PTHREAD_MUTEX_INITIALIZER;
  static smtp_message_t message;
  static auth_context_t authctx = NULL;
  
@@@ -117,23 -113,17 +117,23 @@@ static int notify_email_init (void
  {
    char server[MAXSTRING];
  
 +  ssnprintf(server, sizeof (server), "%s:%i",
 +      (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
 +      smtp_port);
 +
 +  pthread_mutex_lock (&session_lock);
 +
    auth_client_init();
 -  if (!(session = smtp_create_session ())) {
 +
 +  session = smtp_create_session ();
 +  if (session == NULL) {
 +    pthread_mutex_unlock (&session_lock);
      ERROR ("notify_email plugin: cannot create SMTP session");
      return (-1);
    }
  
    smtp_set_monitorcb (session, monitor_cb, NULL, 1);
    smtp_set_hostname (session, hostname_g);
 -  ssnprintf(server, sizeof (server), "%s:%i",
 -      (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
 -      smtp_port);
    smtp_set_server (session, server);
  
    if (smtp_user && smtp_password) {
    }
  
    if ( !smtp_auth_set_context (session, authctx)) {
 +    pthread_mutex_unlock (&session_lock);
      ERROR ("notify_email plugin: cannot set SMTP auth context");
      return (-1);   
    }
  
 +  pthread_mutex_unlock (&session_lock);
    return (0);
  } /* int notify_email_init */
  
  static int notify_email_shutdown (void)
  {
 -  smtp_destroy_session (session);
 -  auth_destroy_context (authctx);
 +  pthread_mutex_lock (&session_lock);
 +
 +  if (session != NULL)
 +    smtp_destroy_session (session);
 +  session = NULL;
 +
 +  if (authctx != NULL)
 +    auth_destroy_context (authctx);
 +  authctx = NULL;
 +
    auth_client_exit();
 +
 +  pthread_mutex_unlock (&session_lock);
    return (0);
  } /* int notify_email_shutdown */
  
@@@ -230,6 -208,7 +230,7 @@@ static int notify_email_notification (c
  {
    smtp_recipient_t recipient;
  
+   time_t tt;
    struct tm timestamp_tm;
    char timestamp_str[64];
  
        (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';
        n->host,
        n->message);
  
 +  pthread_mutex_lock (&session_lock);
 +
 +  if (session == NULL) {
 +    /* Initialization failed or we're in the process of shutting down. */
 +    pthread_mutex_unlock (&session_lock);
 +    return (-1);
 +  }
 +
    if (!(message = smtp_add_message (session))) {
 +    pthread_mutex_unlock (&session_lock);
      ERROR ("notify_email plugin: cannot set SMTP message");
      return (-1);   
    }
      char buf[MAXSTRING];
      ERROR ("notify_email plugin: SMTP server problem: %s",
          smtp_strerror (smtp_errno (), buf, sizeof buf));
 +    pthread_mutex_unlock (&session_lock);
      return (-1);
    } else {
      const smtp_status_t *status;
      smtp_enumerate_recipients (message, print_recipient_status, NULL);
    }
  
 +  pthread_mutex_unlock (&session_lock);
    return (0);
  } /* int notify_email_notification */
  
diff --combined src/python.c
@@@ -435,8 -435,8 +435,8 @@@ static int cpy_write_callback(const dat
                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 +465,7 @@@ static int cpy_notification_callback(co
                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. */
@@@ -978,7 -978,6 +978,7 @@@ PyMODINIT_FUNC PyInit_collectd(void) 
  
  static int cpy_config(oconfig_item_t *ci) {
        int i;
 +      char *argv = "";
        PyObject *sys, *tb;
        PyObject *sys_path;
        PyObject *module;
                cpy_log_exception("python initialization");
                return 1;
        }
 +      PySys_SetArgv(1, &argv);
 +      PyList_SetSlice(sys_path, 0, 1, NULL);
 +
  #ifdef IS_PY3K
        module = PyImport_ImportModule("collectd");
  #else
diff --combined src/utils_cache.c
@@@ -38,13 -38,13 +38,13 @@@ typedef struct cache_entry_
        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 +164,7 @@@ static int uc_send_notification (const 
     * 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)
    }
      
    /* Check if the entry has been updated in the meantime */
 -  if ((n.time - ce->last_update) < (2 * ce->interval))
 +  if ((n.time - ce->last_update) < (timeout_g * ce->interval))
    {
      ce->state = STATE_OKAY;
      pthread_mutex_unlock (&cache_lock);
    }
  
    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 +258,7 @@@ static int uc_insert (const data_set_t 
        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;
        
    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 +300,7 @@@ int uc_init (void
  
  int uc_check_timeout (void)
  {
-   time_t now;
+   cdtime_t now;
    cache_entry_t *ce;
  
    char **keys = NULL;
    
    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 +448,7 @@@ int uc_update (const data_set_t *ds, co
    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;
    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);
    }
  
    {
      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++)
          }
  
          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;
          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;
  
    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 +684,14 @@@ gauge_t *uc_get_rate (const data_set_t 
    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;
  
      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;