From: Florian Forster Date: Fri, 7 Sep 2012 09:05:48 +0000 (+0200) Subject: Merge branch 'collectd-4.10' into collectd-5.0 X-Git-Tag: collectd-5.0.5~7 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=b4c8f3f762d666742c774ab3b45815e5a416e5da;hp=-c;p=collectd.git Merge branch 'collectd-4.10' into collectd-5.0 --- b4c8f3f762d666742c774ab3b45815e5a416e5da diff --combined src/Makefile.am index 782fad91,29aac6a9..72a2e389 --- a/src/Makefile.am +++ b/src/Makefile.am @@@ -21,7 -21,7 +21,7 @@@ AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdi AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' sbin_PROGRAMS = collectd collectdmon -bin_PROGRAMS = collectd-nagios +bin_PROGRAMS = collectd-nagios collectdctl collectd_SOURCES = collectd.c collectd.h \ common.c common.h \ @@@ -40,13 -40,13 +40,13 @@@ utils_match.c utils_match.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) collectd_CFLAGS = $(AM_CFLAGS) collectd_LDFLAGS = -export-dynamic - collectd_LDADD = + collectd_LDADD = -lm collectd_DEPENDENCIES = # Link to these libraries.. @@@ -73,7 -73,6 +73,6 @@@ collectd_LDADD += -ldevinf endif if BUILD_AIX collectd_LDFLAGS += -Wl,-bexpall,-brtllib - collectd_LDADD += -lm endif # The daemon needs to call sg_init, so we need to link it against libstatgrab, @@@ -105,36 -104,11 +104,36 @@@ endi collectd_nagios_LDADD += libcollectdclient/libcollectdclient.la collectd_nagios_DEPENDENCIES = libcollectdclient/libcollectdclient.la + +collectdctl_SOURCES = collectdctl.c +collectdctl_LDADD = +if BUILD_WITH_LIBSOCKET +collectdctl_LDADD += -lsocket +endif +if BUILD_AIX +collectdctl_LDADD += -lm +endif +collectdctl_LDADD += libcollectdclient/libcollectdclient.la +collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la + + 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 @@@ -526,15 -500,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 @@@ -921,16 -886,6 +920,16 @@@ collectd_LDADD += "-dlopen" protocols.l collectd_DEPENDENCIES += protocols.la endif +if BUILD_PLUGIN_REDIS +pkglib_LTLIBRARIES += redis.la +redis_la_SOURCES = redis.c +redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS) +redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS) +redis_la_LIBADD = -lcredis +collectd_LDADD += "-dlopen" redis.la +collectd_DEPENDENCIES += redis.la +endif + if BUILD_PLUGIN_ROUTEROS pkglib_LTLIBRARIES += routeros.la routeros_la_SOURCES = routeros.c @@@ -1088,14 -1043,6 +1087,14 @@@ collectd_LDADD += "-dlopen" target_set. collectd_DEPENDENCIES += target_set.la endif +if BUILD_PLUGIN_TARGET_V5UPGRADE +pkglib_LTLIBRARIES += target_v5upgrade.la +target_v5upgrade_la_SOURCES = target_v5upgrade.c +target_v5upgrade_la_LDFLAGS = -module -avoid-version +collectd_LDADD += "-dlopen" target_v5upgrade.la +collectd_DEPENDENCIES += target_v5upgrade.la +endif + if BUILD_PLUGIN_TCPCONNS pkglib_LTLIBRARIES += tcpconns.la tcpconns_la_SOURCES = tcpconns.c @@@ -1132,14 -1079,6 +1131,14 @@@ collectd_LDADD += "-dlopen" thermal.l collectd_DEPENDENCIES += thermal.la endif +if BUILD_PLUGIN_THRESHOLD +pkglib_LTLIBRARIES += threshold.la +threshold_la_SOURCES = threshold.c +threshold_la_LDFLAGS = -module -avoid-version +collectd_LDADD += "-dlopen" threshold.la +collectd_DEPENDENCIES += threshold.la +endif + if BUILD_PLUGIN_TOKYOTYRANT pkglib_LTLIBRARIES += tokyotyrant.la tokyotyrant_la_SOURCES = tokyotyrant.c @@@ -1158,6 -1097,7 +1157,6 @@@ pkglib_LTLIBRARIES += unixsock.l unixsock_la_SOURCES = unixsock.c \ utils_cmd_flush.h utils_cmd_flush.c \ utils_cmd_getval.h utils_cmd_getval.c \ - utils_cmd_getthreshold.h utils_cmd_getthreshold.c \ utils_cmd_listval.h utils_cmd_listval.c \ utils_cmd_putval.h utils_cmd_putval.c \ utils_cmd_putnotif.h utils_cmd_putnotif.c @@@ -1204,16 -1144,6 +1203,16 @@@ collectd_LDADD += "-dlopen" uuid.l collectd_DEPENDENCIES += uuid.la endif +if BUILD_PLUGIN_VARNISH +pkglib_LTLIBRARIES += varnish.la +varnish_la_SOURCES = varnish.c +varnish_la_LDFLAGS = -module -avoid-version +varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS) +varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS) +collectd_LDADD += "-dlopen" varnish.la +collectd_DEPENDENCIES += varnish.la +endif + if BUILD_PLUGIN_VMEM pkglib_LTLIBRARIES += vmem.la vmem_la_SOURCES = vmem.c @@@ -1253,16 -1183,6 +1252,16 @@@ endi collectd_DEPENDENCIES += write_http.la endif +if BUILD_PLUGIN_WRITE_REDIS +pkglib_LTLIBRARIES += write_redis.la +write_redis_la_SOURCES = write_redis.c +write_redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS) +write_redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS) +write_redis_la_LIBADD = -lcredis +collectd_LDADD += "-dlopen" write_redis.la +collectd_DEPENDENCIES += write_redis.la +endif + if BUILD_PLUGIN_XMMS pkglib_LTLIBRARIES += xmms.la xmms_la_SOURCES = xmms.c @@@ -1287,14 -1207,12 +1286,14 @@@ dist_man_MANS = collectd.1 collectd.conf.5 \ collectd-email.5 \ collectd-exec.5 \ + collectdctl.1 \ collectd-java.5 \ collectdmon.1 \ collectd-nagios.1 \ collectd-perl.5 \ collectd-python.5 \ collectd-snmp.5 \ + collectd-threshold.5 \ collectd-unixsock.5 \ types.db.5 @@@ -1305,7 -1223,6 +1304,7 @@@ EXTRA_DIST = types.db pinba.prot EXTRA_DIST += collectd.conf.pod \ collectd-email.pod \ collectd-exec.pod \ + collectdctl.pod \ collectd-java.pod \ collectdmon.pod \ collectd-nagios.pod \ @@@ -1313,7 -1230,6 +1312,7 @@@ collectd-python.pod \ collectd.pod \ collectd-snmp.pod \ + collectd-threshold.pod \ collectd-unixsock.pod \ postgresql_default.conf \ types.db.pod @@@ -1335,7 -1251,7 +1334,7 @@@ fi pinba.pb-c.c pinba.pb-c.h: pinba.proto - protoc-c --c_out $(builddir) pinba.proto + protoc-c --c_out . pinba.proto install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(sysconfdir) diff --combined src/collectd.c index d33d1d66,b68aea5c..915560c0 --- a/src/collectd.c +++ b/src/collectd.c @@@ -40,7 -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,9 -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; @@@ -141,25 -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) @@@ -182,10 -170,11 +182,11 @@@ static int change_basedir (const char *orig_dir) { - char *dir = strdup (orig_dir); - int dirlen; + char *dir; + size_t dirlen; int status; + dir = strdup (orig_dir); if (dir == NULL) { char errbuf[1024]; @@@ -202,39 -191,41 +203,41 @@@ return (-1); status = chdir (dir); - free (dir); + if (status == 0) + { + free (dir); + return (0); + } + else if (errno != ENOENT) + { + char errbuf[1024]; + ERROR ("change_basedir: chdir (%s): %s", dir, + sstrerror (errno, errbuf, sizeof (errbuf))); + free (dir); + return (-1); + } + status = mkdir (dir, S_IRWXU | S_IRWXG | S_IRWXO); if (status != 0) { - if (errno == ENOENT) - { - if (mkdir (orig_dir, 0755) == -1) - { - char errbuf[1024]; - ERROR ("change_basedir: mkdir (%s): %s", orig_dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - else if (chdir (orig_dir) == -1) - { - char errbuf[1024]; - ERROR ("chdir (%s): %s", orig_dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - else - { - char errbuf[1024]; - ERROR ("chdir (%s): %s", orig_dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } + char errbuf[1024]; + ERROR ("change_basedir: mkdir (%s): %s", dir, + sstrerror (errno, errbuf, sizeof (errbuf))); + free (dir); + return (-1); } + status = chdir (dir); + if (status != 0) + { + char errbuf[1024]; + ERROR ("change_basedir: chdir (%s): %s", dir, + sstrerror (errno, errbuf, sizeof (errbuf))); + free (dir); + return (-1); + } + + free (dir); return (0); } /* static int change_basedir (char *dir) */ @@@ -323,14 -314,22 +326,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 (); @@@ -339,20 -338,27 +342,20 @@@ /* 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) { @@@ -365,6 -371,7 +368,6 @@@ } } /* while (loop == 0) */ - DEBUG ("return (0);"); return (0); } /* int do_loop */ diff --combined src/collectd.conf.pod index 1c0f4f07,75f79429..bee566cd --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@@ -25,22 -25,32 +25,32 @@@ controls which plugins to load. These p behavior. The syntax of this config file is similar to the config file of the famous - B. Each line contains either a key-value-pair or a - section-start or -end. Empty lines and everything after the hash-symbol `#' is - ignored. Values are either string, enclosed in double-quotes, - (floating-point-)numbers or a boolean expression, i.Ee. either B or - B. String containing of only alphanumeric characters and underscores do - not need to be quoted. Lines may be wrapped by using `\' as the last character - before the newline. This allows long lines to be split into multiple lines. - Quoted strings may be wrapped as well. However, those are treated special in - that whitespace at the beginning of the following lines will be ignored, which - allows for nicely indenting the wrapped lines. - - The configuration is read and processed in order, i.Ee. from top to - bottom. So the plugins are loaded in the order listed in this config file. It - is a good idea to load any logging plugins first in order to catch messages - from plugins during configuration. Also, the C option B occur - B the CPlugin ...E> block. + I webserver. Each line contains either an option (a key and a list of + one or more values) or a section-start or -end. Empty lines and everything + after a non-quoted hash-symbol (C<#>) is ignored. I are unquoted + strings, consisting only of alphanumeric characters and the underscore (C<_>) + character. Keys are handled case insensitive by I itself and all + plugins included with it. I can either be an I, a + I (enclosed in double-quotes) a I or a I + expression. I consist of only alphanumeric characters and + underscores (C<_>) and do not need to be quoted. I are + enclosed in double quotes (C<">). You can use the backslash character (C<\>) + to include double quotes as part of the string. I can be specified in + decimal and floating point format (using a dot C<.> as decimal separator), + hexadecimal when using the C<0x> prefix and octal with a leading zero (C<0>). + I values are either B or B. + + Lines may be wrapped by using C<\> as the last character before the newline. + This allows long lines to be split into multiple lines. Quoted strings may be + wrapped as well. However, those are treated special in that whitespace at the + beginning of the following lines will be ignored, which allows for nicely + indenting the wrapped lines. + + The configuration is read and processed in order, i.e. from top to bottom. So + the plugins are loaded in the order listed in this config file. It is a good + idea to load any logging plugins first in order to catch messages from plugins + during configuration. Also, the C option B occur B + the appropriate CPlugin ...E> block. =head1 GLOBAL OPTIONS @@@ -72,19 -82,15 +82,19 @@@ options are allowed inside a Bg., when loading a plugin -that embeds some scripting language into the daemon (e.Eg. the C -or C plugins). Scripting languages usually provide means to load +This is useful (or possibly even required), e.g., when loading a plugin that +embeds some scripting language into the daemon (e.g. the I and +I). Scripting languages usually provide means to load extensions written in C. Those extensions require symbols provided by the -interpreter, which is loaded as a dependency of the respective collectd -plugin. See the documentation of those plugins (e.Eg., -L or L) for details. +interpreter, which is loaded as a dependency of the respective collectd plugin. +See the documentation of those plugins (e.g., L or +L) for details. + +By default, this is disabled. As a special exception, if the plugin name is +either C or C, the default is changed to enabled in order to keep +the average user from ever having to deal with this low level linking stuff. =back @@@ -145,7 -151,7 +155,7 @@@ missing when no update has been receive this setting uses iterations, the maximum allowed time without update depends on the I information contained in each value list. This is used in the I configuration to dispatch notifications about missing values, -see L<"THRESHOLD CONFIGURATION"> below. +see L for details. =item B I @@@ -163,8 -169,13 +173,8 @@@ hostname will be determined using the L If B is determined automatically this setting controls whether or not the daemon should try to figure out the "fully qualified domain name", FQDN. -This is done using a lookup of the name returned by C. - -Using this feature (i.Ee. setting this option to B) is recommended. -However, to preserve backwards compatibility the default is set to B. -The sample config file that is installed with Cinstall> includes a -line which sets this option, though, so that default installations will have -this setting enabled. +This is done using a lookup of the name returned by C. This option +is enabled by default. =item B I @@@ -189,143 -200,6 +199,143 @@@ A list of all plugins and a short summa F file shipped with the sourcecode and hopefully binary packets as well. +=head2 Plugin C + +The I can be used to communicate with other instances of +I or third party applications using an AMQP message broker. Values +are sent to or received from the broker, which handles routing, queueing and +possibly filtering or messages. + + + # Send values to an AMQP broker + + Host "localhost" + Port "5672" + VHost "/" + User "guest" + Password "guest" + Exchange "amq.fanout" + # ExchangeType "fanout" + # RoutingKey "collectd" + # Persistent false + # Format "command" + # StoreRates false + + + # Receive values from an AMQP broker + + Host "localhost" + Port "5672" + VHost "/" + User "guest" + Password "guest" + Exchange "amq.fanout" + # ExchangeType "fanout" + # Queue "queue_name" + # RoutingKey "collectd.#" + + + +The plugin's configuration consists of a number of I and I +blocks, which configure sending and receiving of values respectively. The two +blocks are very similar, so unless otherwise noted, an option can be used in +either block. The name given in the blocks starting tag is only used for +reporting messages, but may be used to support I of certain +I blocks in the future. + +=over 4 + +=item B I + +Hostname or IP-address of the AMQP broker. Defaults to the default behavior of +the underlying communications library, I, which is "localhost". + +=item B I + +Service name or port number on which the AMQP broker accepts connections. This +argument must be a string, even if the numeric form is used. Defaults to +"5672". + +=item B I + +Name of the I on the AMQP broker to use. Defaults to "/". + +=item B I + +=item B I + +Credentials used to authenticate to the AMQP broker. By default "guest"/"guest" +is used. + +=item B I + +In I blocks, this option specifies the I to send values to. +By default, "amq.fanout" will be used. + +In I blocks this option is optional. If given, a I between +the given exchange and the I is created, using the I if +configured. See the B and B options below. + +=item B I + +If given, the plugin will try to create the configured I with this +I after connecting. When in a I block, the I will then +be bound to this exchange. + +=item B I (Subscribe only) + +Configures the I name to subscribe to. If no queue name was configures +explicitly, a unique queue name will be created by the broker. + +=item B I + +In I blocks, this configures the routing key to set on all outgoing +messages. If not given, the routing key will be computed from the I +of the value. The host, plugin, type and the two instances are concatenated +together using dots as the separator and all containing dots replaced with +slashes. For example "collectd.host/example/com.cpu.0.cpu.user". This makes it +possible to receive only specific values using a "topic" exchange. + +In I blocks, configures the I used when creating a +I between an I and the I. The usual wildcards can be +used to filter messages when using a "topic" exchange. If you're only +interested in CPU statistics, you could use the routing key "collectd.*.cpu.#" +for example. + +=item B B|B (Publish only) + +Selects the I to use. If set to B, the I +mode will be used, i.e. delivery is guaranteed. If set to B (the +default), the I delivery mode will be used, i.e. messages may be +lost due to high load, overflowing queues or similar issues. + +=item B B|B (Publish only) + +Selects the format in which messages are sent to the broker. If set to +B (the default), values are sent as C commands which are +identical to the syntax used by the I and I. In this +case, the C header field will be set to C. + +If set to B, the values are encoded in the I, +an easy and straight forward exchange format. The C header field +will be set to C. + +A subscribing client I use the C header field to +determine how to decode the values. Currently, the I itself can +only decode the B format. + +=item B B|B (Publish only) + +Determines whether or not C, C and C data sources +are converted to a I (i.e. a C value). If set to B (the +default), no conversion is performed. Otherwise the conversion is performed +using the internal value cache. + +Please note that currently this option is only used if the B option has +been set to B. + +=back + =head2 Plugin C To configure the C-plugin you first need to configure the Apache @@@ -344,25 -218,7 +354,25 @@@ Since its C module is very also supported. It introduces a new field, called C, to count the number of currently connected clients. This field is also supported. -The following options are accepted by the C-plugin: +The configuration of the I plugin consists of one or more +CInstanceE/E> blocks. Each block requires one string argument +as the instance name. For example: + + + + URL "http://www1.example.com/mod_status?auto" + + + URL "http://www2.example.com/mod_status?auto" + + + +The instance name will be used as the I. To emulate the old +(versionE4) behavior, you can use an empty string (""). In order for the +plugin to work correctly, each instance name must be unique. This is not +enforced by the plugin and it is your responsibility to ensure it. + +The following options are accepted within each I block: =over 4 @@@ -370,7 -226,7 +380,7 @@@ Sets the URL of the C output. This needs to be the output generated by C and it needs to be the machine readable output -generated by appending the C argument. +generated by appending the C argument. This option is I. =item B I @@@ -739,6 -595,22 +749,6 @@@ runtime statistics module of CouchD -Another CouchDB example: -The following example will collect the status values from each database: - - - Instance "dbs" - - Type "gauge" - - - Type "counter" - - - Type "bytes" - - - In the B block, there may be one or more B blocks, each defining a URL to be fetched via HTTP (using libcurl) and one or more B blocks. The B string argument must be in a path format, which is used to collect a @@@ -1168,6 -1040,22 +1178,6 @@@ Report using the device name rather tha (the default), it will report a disk as "root", but with it I, it will be "sda1" (or whichever). -=item B B|B - -When enabled, the blocks reserved for root are reported separately. When -disabled (the default for backwards compatibility reasons) the reserved space -will be included in the "free" space. - -When disabled, the "df" type will be used to store "free" and "used" space. The -mount point or disk name (see option B) is used as type -instance in this case (again: backwards compatibility). - -When enabled, the type "df_complex" is used and three files are created. The -mount point or disk name is used as plugin instance and the type instance is -set to "free", "reserved" and "used" as appropriate. - -Enabling this option is recommended. - =item B B|B Enables or disables reporting of free, reserved and used inodes. Defaults to @@@ -1487,6 -1375,13 +1497,6 @@@ Hostname to connect to. Defaults to B<1 TCP-Port to connect to. Defaults to B<7634>. -=item B I|I - -If enabled, translate the disk names to major/minor device numbers -(e.Eg. "8-0" for /dev/sda). For backwards compatibility this defaults to -I but it's recommended to disable it as it will probably be removed in -the next major version. - =back =head2 Plugin C @@@ -1714,16 -1609,6 +1724,16 @@@ You can also specify combinations of th means to concatenate the guest name and UUID (with a literal colon character between, thus I<"foo:1234-1234-1234-1234">). +=item B B|B
+ +When the libvirt plugin logs interface data, it sets the name of the collected +data according to this setting. The default is to use the path as provided by +the hypervisor (the "dev" property of the target node), which is equal to +setting B. + +B
means use the interface's mac address. This is useful since the +interface path might change between reboots of a guest or across migrations. + =back =head2 Plugin C @@@ -1742,8 -1627,8 +1752,8 @@@ debugging support Sets the file to write log messages to. The special strings B and B can be used to write to the standard output and standard error -channels, respectively. This, of course, only makes much sense when collectd is -running in foreground- or non-daemon-mode. +channels, respectively. This, of course, only makes much sense when I +is running in foreground- or non-daemon-mode. =item B B|B @@@ -1760,33 -1645,6 +1770,33 @@@ B: There is no need to notify th log file (e.Eg. when rotating the logs). The plugin reopens the file for each line it writes. +=head2 Plugin C + +The I reads CPU statistics of I, a +virtualization technique for IBM POWER processors. It takes into account CPU +time stolen from or donated to a partition, in addition to the usual user, +system, I/O statistics. + +The following configuration options are available: + +=over 4 + +=item B B|B + +When enabled, statistics about the processor pool are read, too. The partition +needs to have pool authority in order to be able to acquire this information. +Defaults to false. + +=item B B|B + +If enabled, the serial of the physical machine the partition is currently +running on is reported as I and the logical hostname of the machine +is reported in the I. Otherwise, the logical hostname will be +used (just like other plugins) and the I will be empty. +Defaults to false. + +=back + =head2 Plugin C The C uses mbmon to retrieve temperature, voltage, etc. @@@ -2012,7 -1870,7 +2022,7 @@@ B option is mandatory The C requires B to be installed. It connects to one or more databases when started and keeps the connection up as long as possible. When the connection is interrupted for whatever reason it will try -to re-connect. The plugin will complaint loudly in case anything goes wrong. +to re-connect. The plugin will complain loudly in case anything goes wrong. This plugin issues the MySQL C / C command and collects information about MySQL network traffic, executed statements, @@@ -2794,18 -2652,7 +2804,18 @@@ operating systems =item B I<1024-65535> Set the maximum size for datagrams received over the network. Packets larger -than this will be truncated. +than this will be truncated. Defaults to 1452Ebytes, which is the maximum +payload size that can be transmitted in one Ethernet frame using IPv6E/ +UDP. + +On the server side, this limit should be set to the largest value used on +I client. Likewise, the value on the client must not be larger than the +value on the server, or data will be lost. + +B Versions prior to I4.8> used a fixed sized +buffer of 1024Ebytes. Versions I<4.8>, I<4.9> and I<4.10> used a default +value of 1024Ebytes to avoid problems when sending data to an older +server. =item B I @@@ -2816,6 -2663,16 +2826,6 @@@ the same multicast group. While this re necessary it's not a huge problem since the plugin has a duplicate detection, so the values will not loop. -=item B I - -For each host/plugin/type combination the C caches the time of -the last value being sent or received. Every I seconds the plugin -searches and removes all entries that are older than I seconds, thus -freeing the unused memory again. Since this process is somewhat expensive and -normally doesn't do much, this value should not be too small. The default is -1800 seconds, but setting this to 86400 seconds (one day) will not do much harm -either. - =item B B|B The network plugin cannot only receive and send statistics, it can also create @@@ -3450,6 -3307,11 +3460,6 @@@ allowed as long as a single non-empty c The returned lines will be handled separately one after another. -=item B I - -This is a deprecated synonym for B. It will be removed in version 5 -of collectd. - =item B I|I|I|I Specify the parameters which should be passed to the SQL query. The parameters @@@ -3525,6 -3387,21 +3535,6 @@@ This option is required inside a B options are specified, the columns are read in the given order. -=item B I [I] - -This is a deprecated alternative to a B block. It will be removed in -version 5 of collectd. It is equivalent to the following B block: - - - Type I - InstancePrefix I - ValuesFrom I - - -The order of the B options defines which columns of the query result -should be used. The first option specifies the data found in the first column, -the second option that of the second column, and so on. - =item B I =item B I @@@ -3539,6 -3416,13 +3549,6 @@@ The I has to be specified as t and patch-level versions, each represented as two-decimal-digit numbers. For example, version 8.2.3 will become 80203. -=item B I - -=item B I - -These are deprecated synonyms for B and B -respectively. They will be removed in version 5 of collectd. - =back The following predefined queries are available (the definitions can be found @@@ -3949,52 -3833,6 +3959,52 @@@ Defaults to B =back +=head2 Plugin C + +The I connects to one or more Redis servers and gathers +information about each server's state. For each server there is a I block +which configures the connection parameters for this node. + + + + Host "localhost" + Port "6379" + Timeout 2000 + + + +The information shown in the synopsis above is the I +which is used by the plugin if no configuration is present. + +=over 4 + +=item B I + +The B block identifies a new Redis node, that is a new Redis instance +running in an specified host and port. The name for node is a canonical +identifier which is used as I. It is limited to +64Echaracters in length. + +=item B I + +The B option is the hostname or IP-address where the Redis instance is +running on. + +=item B I + +The B option is the TCP port on which the Redis instance accepts +connections. Either a service name of a port number may be given. Please note +that numerical port numbers must be given as a string, too. + +=item B I + +The B option set the socket timeout for node response. Since the Redis +read function is blocking, you should keep this value as low as possible. Keep +in mind that the sum of all B values for all B should be lower +than B defined globally. + +=back + =head2 Plugin C The C plugin uses the RRDtool accelerator daemon, L, @@@ -4158,7 -3996,7 +4168,7 @@@ because all values were added to the in =head2 Plugin C -The C uses B to retrieve sensor-values. This means +The I uses B to retrieve sensor-values. This means that all the needed modules have to be loaded and lm_sensors has to be configured (most likely by editing F. Read L for details. @@@ -4193,25 -4031,6 +4203,25 @@@ Since the configuration of the C. Please see there for details. +=head2 Plugin C + +The I collects information about used and available swap space. On +I, the following options are available: + +=over 4 + +=item B B|B + +Configures how to report physical swap devices. If set to B is used (the +default), the summary over all swap devices is reported only, i.e. the globally +used and available space over all devices. If B is configured, the used +and available space of each device will be reported separately. + +This option is only available if the I can use the L +mechanism under I. + +=back + =head2 Plugin C =over 4 @@@ -4561,7 -4380,7 +4571,7 @@@ port in numeric form =item B I|I -By default, the C plugin tries to read the statistics from the Linux +By default, the I tries to read the statistics from the Linux C interface. If that is not available, the plugin falls back to the C interface. By setting this option to I, you can force the plugin to use the latter. This option defaults to I. @@@ -4581,18 -4400,9 +4591,18 @@@ selection is configured at all, B =back +=head2 Plugin C + +The I checks values collected or received by I +against a configurable I and issues I if values are +out of bounds. + +Documentation for this plugin is available in the L +manual page. + =head2 Plugin C -The C connects to a TokyoTyrant server and collects a +The I connects to a TokyoTyrant server and collects a couple metrics: number of records, and database size on disk. =over 4 @@@ -4629,13 -4439,6 +4639,13 @@@ Change the file permissions of the UNIX permissions must be given as a numeric, octal value as you would pass to L. Defaults to B<0770>. +=item B B|B + +If set to B, delete the socket file before calling L, if a file +with the given name already exists. If I crashes a socket file may be +left over, preventing the daemon from opening a new socket when restarted. +Since this is potentially dangerous, this defaults to B. + =back =head2 Plugin C @@@ -4679,68 -4482,6 +4689,68 @@@ Take the UUID from the given file (defa =back +=head2 Plugin C + +The Varnish plugin collects information about Varnish, an HTTP accelerator. + +=over 4 + +=item B B|B + +Cache hits and misses. True by default. + +=item B B|B + +Number of client connections received, accepted and dropped. True by default. + +=item B B|B + +Back-end connection statistics, such as successful, reused, +and closed connections. True by default. + +=item B B|B + +Statistics about the shared memory log, a memory region to store +log messages which is flushed to disk when full. True by default. + +=item B B|B + +Edge Side Includes (ESI) parse statistics. False by default. + +=item B B|B + +Statistics about fetches (HTTP requests sent to the backend). False by default. + +=item B B|B + +Inserts and look-ups in the crit bit tree based hash. Look-ups are +divided into locked and unlocked look-ups. False by default. + +=item B B|B + +malloc or umem (umem_alloc(3MALLOC) based) storage statistics. +The umem storage component is Solaris specific. False by default. + +=item B B|B + +synth (synthetic content) storage statistics. This storage +component is used internally only. False by default. + +=item B B|B + +file (memory mapped file) storage statistics. False by default. + +=item B B|B + +Collects overview counters, such as the number of sessions created, +the number of requests and bytes transferred. False by default. + +=item B B|B + +Collect statistics about worker threads. False by default. + +=back + =head2 Plugin C The C plugin collects information about the usage of virtual memory. diff --combined src/common.c index 459c7024,3bab7a59..406482ad --- a/src/common.c +++ b/src/common.c @@@ -1,6 -1,6 +1,6 @@@ /** * collectd - src/common.c - * Copyright (C) 2005-2009 Florian octo Forster + * Copyright (C) 2005-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 @@@ -16,7 -16,7 +16,7 @@@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Niki W. Waibel * Sebastian Harl * Michał Mirosław @@@ -29,7 -29,6 +29,7 @@@ #include "collectd.h" #include "common.h" #include "plugin.h" +#include "utils_cache.h" #if HAVE_PTHREAD_H # include @@@ -39,6 -38,11 +39,6 @@@ # include #endif -/* for ntohl and htonl */ -#if HAVE_ARPA_INET_H -# include -#endif - /* for getaddrinfo */ #include #include @@@ -48,11 -52,6 +48,11 @@@ # include #endif +/* for ntohl and htonl */ +#if HAVE_ARPA_INET_H +# include +#endif + #ifdef HAVE_LIBKSTAT extern kstat_ctl_t *kc; #endif @@@ -548,7 -547,7 +548,7 @@@ int check_create_dir (const char *file_ { if (errno == ENOENT) { - if (mkdir (dir, 0755) == 0) + if (mkdir (dir, S_IRWXU | S_IRWXG | S_IRWXO) == 0) break; /* this might happen, if a different thread created @@@ -804,75 -803,6 +804,75 @@@ int format_name (char *ret, int ret_len return (0); } /* int format_name */ +int format_values (char *ret, size_t ret_len, /* {{{ */ + const data_set_t *ds, const value_list_t *vl, + _Bool store_rates) +{ + size_t offset = 0; + int status; + int i; + gauge_t *rates = NULL; + + assert (0 == strcmp (ds->type, vl->type)); + + memset (ret, 0, ret_len); + +#define BUFFER_ADD(...) do { \ + status = ssnprintf (ret + offset, ret_len - offset, \ + __VA_ARGS__); \ + if (status < 1) \ + { \ + sfree (rates); \ + return (-1); \ + } \ + else if (((size_t) status) >= (ret_len - offset)) \ + { \ + sfree (rates); \ + return (-1); \ + } \ + else \ + offset += ((size_t) status); \ +} while (0) + + BUFFER_ADD ("%.3f", CDTIME_T_TO_DOUBLE (vl->time)); + + for (i = 0; i < ds->ds_num; i++) + { + if (ds->ds[i].type == DS_TYPE_GAUGE) + BUFFER_ADD (":%f", vl->values[i].gauge); + else if (store_rates) + { + if (rates == NULL) + rates = uc_get_rate (ds, vl); + if (rates == NULL) + { + WARNING ("format_values: " + "uc_get_rate failed."); + return (-1); + } + BUFFER_ADD (":%g", rates[i]); + } + else if (ds->ds[i].type == DS_TYPE_COUNTER) + BUFFER_ADD (":%llu", vl->values[i].counter); + else if (ds->ds[i].type == DS_TYPE_DERIVE) + BUFFER_ADD (":%"PRIi64, vl->values[i].derive); + else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) + BUFFER_ADD (":%"PRIu64, vl->values[i].absolute); + else + { + ERROR ("format_values plugin: Unknown data source type: %i", + ds->ds[i].type); + sfree (rates); + return (-1); + } + } /* for ds->ds_num */ + +#undef BUFFER_ADD + + sfree (rates); + return (0); +} /* }}} int format_values */ + int parse_identifier (char *str, char **ret_host, char **ret_plugin, char **ret_plugin_instance, char **ret_type, char **ret_type_instance) @@@ -919,40 -849,6 +919,40 @@@ return (0); } /* int parse_identifier */ +int parse_identifier_vl (const char *str, value_list_t *vl) /* {{{ */ +{ + char str_copy[6 * DATA_MAX_NAME_LEN]; + char *host = NULL; + char *plugin = NULL; + char *plugin_instance = NULL; + char *type = NULL; + char *type_instance = NULL; + int status; + + if ((str == NULL) || (vl == NULL)) + return (EINVAL); + + sstrncpy (str_copy, str, sizeof (str_copy)); + + status = parse_identifier (str_copy, &host, + &plugin, &plugin_instance, + &type, &type_instance); + if (status != 0) + return (status); + + sstrncpy (vl->host, host, sizeof (vl->host)); + sstrncpy (vl->plugin, plugin, sizeof (vl->plugin)); + sstrncpy (vl->plugin_instance, + (plugin_instance != NULL) ? plugin_instance : "", + sizeof (vl->plugin_instance)); + sstrncpy (vl->type, type, sizeof (vl->type)); + sstrncpy (vl->type_instance, + (type_instance != NULL) ? type_instance : "", + sizeof (vl->type_instance)); + + return (0); +} /* }}} int parse_identifier_vl */ + int parse_value (const char *value_orig, value_t *ret_value, int ds_type) { char *value; @@@ -1036,22 -932,9 +1036,22 @@@ int parse_values (char *buffer, value_l 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 { diff --combined src/df.c index 41a03cbf,dc7be1eb..ded374b9 --- a/src/df.c +++ b/src/df.c @@@ -62,8 -62,9 +62,8 @@@ static ignorelist_t *il_device = NULL static ignorelist_t *il_mountpoint = NULL; static ignorelist_t *il_fstype = NULL; -static _Bool by_device = false; -static _Bool report_reserved = false; -static _Bool report_inodes = false; +static _Bool by_device = 0; +static _Bool report_inodes = 0; static int df_init (void) { @@@ -118,16 -119,25 +118,16 @@@ static int df_config (const char *key, else if (strcasecmp (key, "ReportByDevice") == 0) { if (IS_TRUE (value)) - by_device = true; - - return (0); - } - else if (strcasecmp (key, "ReportReserved") == 0) - { - if (IS_TRUE (value)) - report_reserved = true; - else - report_reserved = false; + by_device = 1; return (0); } else if (strcasecmp (key, "ReportInodes") == 0) { if (IS_TRUE (value)) - report_inodes = true; + report_inodes = 1; else - report_inodes = false; + report_inodes = 0; return (0); } @@@ -136,6 -146,28 +136,6 @@@ return (-1); } -static void df_submit_two (char *df_name, - const char *type, - gauge_t df_used, - gauge_t df_free) -{ - value_t values[2]; - value_list_t vl = VALUE_LIST_INIT; - - values[0].gauge = df_used; - values[1].gauge = df_free; - - vl.values = values; - vl.values_len = 2; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "df", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, df_name, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); -} /* void df_submit_two */ - __attribute__ ((nonnull(2))) static void df_submit_one (char *plugin_instance, const char *type, const char *type_instance, @@@ -183,9 -215,6 +183,9 @@@ static int df_read (void { unsigned long long blocksize; char disk_name[256]; + uint64_t blk_free; + uint64_t blk_reserved; + uint64_t blk_used; if (ignorelist_match (il_device, (mnt_ptr->spec_device != NULL) @@@ -228,6 -257,8 +228,8 @@@ { if (strcmp (mnt_ptr->dir, "/") == 0) { + if (strcmp (mnt_ptr->type, "rootfs") == 0) + continue; sstrncpy (disk_name, "root", sizeof (disk_name)); } else @@@ -245,39 -276,56 +247,39 @@@ blocksize = BLOCKSIZE(statbuf); - if (report_reserved) - { - uint64_t blk_free; - uint64_t blk_reserved; - uint64_t blk_used; - - /* - * Sanity-check for the values in the struct - */ - /* Check for negative "available" byes. For example UFS can - * report negative free space for user. Notice. blk_reserved - * will start to diminish after this. */ + /* + * Sanity-check for the values in the struct + */ + /* Check for negative "available" byes. For example UFS can + * report negative free space for user. Notice. blk_reserved + * will start to diminish after this. */ #if HAVE_STATVFS - /* Cast and temporary variable are needed to avoid - * compiler warnings. - * ((struct statvfs).f_bavail is unsigned (POSIX)) */ - int64_t signed_bavail = (int64_t) statbuf.f_bavail; - if (signed_bavail < 0) - statbuf.f_bavail = 0; + /* Cast and temporary variable are needed to avoid + * compiler warnings. + * ((struct statvfs).f_bavail is unsigned (POSIX)) */ + int64_t signed_bavail = (int64_t) statbuf.f_bavail; + if (signed_bavail < 0) + statbuf.f_bavail = 0; #elif HAVE_STATFS - if (statbuf.f_bavail < 0) - statbuf.f_bavail = 0; + if (statbuf.f_bavail < 0) + statbuf.f_bavail = 0; #endif - /* Make sure that f_blocks >= f_bfree >= f_bavail */ - if (statbuf.f_bfree < statbuf.f_bavail) - statbuf.f_bfree = statbuf.f_bavail; - if (statbuf.f_blocks < statbuf.f_bfree) - statbuf.f_blocks = statbuf.f_bfree; - - blk_free = (uint64_t) statbuf.f_bavail; - blk_reserved = (uint64_t) (statbuf.f_bfree - statbuf.f_bavail); - blk_used = (uint64_t) (statbuf.f_blocks - statbuf.f_bfree); - - df_submit_one (disk_name, "df_complex", "free", - (gauge_t) (blk_free * blocksize)); - df_submit_one (disk_name, "df_complex", "reserved", - (gauge_t) (blk_reserved * blocksize)); - df_submit_one (disk_name, "df_complex", "used", - (gauge_t) (blk_used * blocksize)); - } - else /* compatibility code */ - { - gauge_t df_free; - gauge_t df_used; - - df_free = statbuf.f_bfree * blocksize; - df_used = (statbuf.f_blocks - statbuf.f_bfree) * blocksize; - - df_submit_two (disk_name, "df", df_used, df_free); - } + /* Make sure that f_blocks >= f_bfree >= f_bavail */ + if (statbuf.f_bfree < statbuf.f_bavail) + statbuf.f_bfree = statbuf.f_bavail; + if (statbuf.f_blocks < statbuf.f_bfree) + statbuf.f_blocks = statbuf.f_bfree; + + blk_free = (uint64_t) statbuf.f_bavail; + blk_reserved = (uint64_t) (statbuf.f_bfree - statbuf.f_bavail); + blk_used = (uint64_t) (statbuf.f_blocks - statbuf.f_bfree); + + df_submit_one (disk_name, "df_complex", "free", + (gauge_t) (blk_free * blocksize)); + df_submit_one (disk_name, "df_complex", "reserved", + (gauge_t) (blk_reserved * blocksize)); + df_submit_one (disk_name, "df_complex", "used", + (gauge_t) (blk_used * blocksize)); /* inode handling */ if (report_inodes) diff --combined src/memcachec.c index 8f51e22f,73faa506..c57a8312 --- a/src/memcachec.c +++ b/src/memcachec.c @@@ -328,7 -328,7 +328,7 @@@ static int cmc_config_add_page (oconfig if (strcasecmp ("Server", child->key) == 0) status = cmc_config_add_string ("Server", &page->server, child); - if (strcasecmp ("Key", child->key) == 0) + else if (strcasecmp ("Key", child->key) == 0) status = cmc_config_add_string ("Key", &page->key, child); else if (strcasecmp ("Match", child->key) == 0) /* Be liberal with failing matches => don't set `status'. */ @@@ -452,6 -452,7 +452,6 @@@ static void cmc_submit (const web_page_ vl.values = values; vl.values_len = 1; - vl.time = time (NULL); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "memcachec", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); diff --combined src/netapp.c index d9bd1ae5,c9ff6b59..f7bc04d3 --- a/src/netapp.c +++ b/src/netapp.c @@@ -1,6 -1,6 +1,6 @@@ /** * collectd - src/netapp.c - * Copyright (C) 2009 Sven Trenkel + * Copyright (C) 2009,2010 Sven Trenkel * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@@ -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; @@@ -104,7 -104,7 +104,7 @@@ 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 interval) { value_list_t vl = VALUE_LIST_INIT; @@@ -593,34 -593,33 +593,34 @@@ return (plugin_dispatch_values (&vl)); } /* }}} int submit_uint64 */ -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) +static int submit_two_derive (const char *host, const char *plugin_inst, /* {{{ */ + const char *type, const char *type_inst, derive_t val0, derive_t val1, + cdtime_t timestamp, cdtime_t interval) { value_t values[2]; - values[0].counter = val0; - values[1].counter = val1; + values[0].derive = val0; + values[1].derive = val1; return (submit_values (host, plugin_inst, type, type_inst, values, 2, timestamp, interval)); -} /* }}} int submit_two_counters */ +} /* }}} int submit_two_derive */ -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) +static int submit_derive (const char *host, const char *plugin_inst, /* {{{ */ + const char *type, const char *type_inst, derive_t counter, + cdtime_t timestamp, cdtime_t interval) { value_t v; - v.counter = counter; + v.derive = counter; return (submit_values (host, plugin_inst, type, type_inst, &v, 1, timestamp, interval)); -} /* }}} int submit_counter */ +} /* }}} int submit_derive */ 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]; @@@ -632,8 -631,7 +632,8 @@@ } /* }}} 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; @@@ -652,8 -650,8 +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 interval) { value_t v; @@@ -744,16 -742,16 +744,16 @@@ static int submit_volume_perf_data (con if (HAS_ALL_FLAGS (old_data->flags, CFG_VOLUME_PERF_IO) && 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, interval); + submit_two_derive (hostname, plugin_instance, "disk_octets", /* type instance = */ NULL, + (derive_t) new_data->read_bytes, (derive_t) new_data->write_bytes, new_data->timestamp, interval); } /* Check for and submit disk-operations values */ if (HAS_ALL_FLAGS (old_data->flags, CFG_VOLUME_PERF_OPS) && 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, interval); + submit_two_derive (hostname, plugin_instance, "disk_ops", /* type instance = */ NULL, + (derive_t) new_data->read_ops, (derive_t) new_data->write_ops, new_data->timestamp, interval); } /* Check for, calculate and submit disk-latency values */ @@@ -818,16 -816,6 +818,16 @@@ 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 * @@@ -847,7 -835,7 +847,7 @@@ static int cna_handle_wafl_data (const 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) @@@ -962,7 -950,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); @@@ -971,7 -959,7 +971,7 @@@ 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); @@@ -1000,9 -988,9 +1000,9 @@@ /* Data corresponding to */ 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; @@@ -1011,7 -999,7 +1011,7 @@@ 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) @@@ -1156,7 -1144,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); @@@ -1166,7 -1154,7 +1166,7 @@@ 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); @@@ -1195,14 -1183,14 +1195,14 @@@ /* Data corresponding to */ 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) @@@ -1327,7 -1315,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); @@@ -1337,7 -1325,7 +1337,7 @@@ 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); @@@ -1456,7 -1444,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)); @@@ -1694,7 -1682,7 +1694,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); @@@ -1704,7 -1692,7 +1704,7 @@@ 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); @@@ -1739,15 -1727,15 +1739,15 @@@ static int cna_handle_system_data (cons na_elem_t *counter; na_elem_iter_t counter_iter; - counter_t disk_read = 0, disk_written = 0; - counter_t net_recv = 0, net_sent = 0; - counter_t cpu_busy = 0, cpu_total = 0; + derive_t disk_read = 0, disk_written = 0; + derive_t net_recv = 0, net_sent = 0; + derive_t cpu_busy = 0, cpu_total = 0; 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) @@@ -1784,47 -1772,47 +1784,47 @@@ continue; if (!strcmp(name, "disk_data_read")) { - disk_read = (counter_t) (value * 1024); + disk_read = (derive_t) (value * 1024); counter_flags |= 0x01; } else if (!strcmp(name, "disk_data_written")) { - disk_written = (counter_t) (value * 1024); + disk_written = (derive_t) (value * 1024); counter_flags |= 0x02; } else if (!strcmp(name, "net_data_recv")) { - net_recv = (counter_t) (value * 1024); + net_recv = (derive_t) (value * 1024); counter_flags |= 0x04; } else if (!strcmp(name, "net_data_sent")) { - net_sent = (counter_t) (value * 1024); + net_sent = (derive_t) (value * 1024); counter_flags |= 0x08; } else if (!strcmp(name, "cpu_busy")) { - cpu_busy = (counter_t) value; + cpu_busy = (derive_t) value; counter_flags |= 0x10; } else if (!strcmp(name, "cpu_elapsed_time")) { - cpu_total = (counter_t) value; + cpu_total = (derive_t) value; counter_flags |= 0x20; } else if ((cfg_system->flags & CFG_SYSTEM_OPS) && (value > 0) && (strlen(name) > 4) && (!strcmp(name + strlen(name) - 4, "_ops"))) { - submit_counter (hostname, instance, "disk_ops_complex", name, - (counter_t) value, timestamp, interval); + submit_derive (hostname, instance, "disk_ops_complex", name, + (derive_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, + submit_two_derive (hostname, instance, "disk_octets", NULL, 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, + submit_two_derive (hostname, instance, "if_octets", NULL, 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", + submit_derive (hostname, instance, "cpu", "system", cpu_busy, timestamp, interval); - submit_counter (hostname, instance, "cpu", "idle", + submit_derive (hostname, instance, "cpu", "idle", cpu_total - cpu_busy, timestamp, interval); } @@@ -1854,7 -1842,7 +1854,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); @@@ -1863,7 -1851,7 +1863,7 @@@ 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); @@@ -1920,12 -1908,23 +1920,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; @@@ -2425,7 -2424,11 +2425,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")) { @@@ -2497,7 -2500,7 +2497,7 @@@ static int cna_init_host (host_config_ na_server_adminuser(host->srv, host->username, host->password); na_server_set_timeout(host->srv, 5 /* seconds */); - return 0; + return (0); } /* }}} int cna_init_host */ static int cna_init (void) /* {{{ */ @@@ -2514,6 -2517,32 +2514,32 @@@ return (0); } /* }}} cna_init */ + static int cna_read_internal (host_config_t *host) { /* {{{ */ + int status; + + status = cna_query_wafl (host); + if (status != 0) + return (status); + + status = cna_query_disk (host); + if (status != 0) + return (status); + + status = cna_query_volume_perf (host); + if (status != 0) + return (status); + + status = cna_query_volume_usage (host); + if (status != 0) + return (status); + + status = cna_query_system (host); + if (status != 0) + return (status); + + return 0; + } /* }}} int cna_read_internal */ + static int cna_read (user_data_t *ud) { /* {{{ */ host_config_t *host; int status; @@@ -2526,12 -2555,14 +2552,14 @@@ status = cna_init_host (host); if (status != 0) return (status); - - cna_query_wafl (host); - cna_query_disk (host); - cna_query_volume_perf (host); - cna_query_volume_usage (host); - cna_query_system (host); + + status = cna_read_internal (host); + if (status != 0) + { + if (host->srv != NULL) + na_server_close (host->srv); + host->srv = NULL; + } return 0; } /* }}} int cna_read */ @@@ -2556,7 -2587,8 +2584,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/oracle.c index 4415b489,828fc2e5..80ae699c --- a/src/oracle.c +++ b/src/oracle.c @@@ -86,6 -86,7 +86,7 @@@ OCIError *oci_error = NULL * Functions */ static void o_report_error (const char *where, /* {{{ */ + const char *db_name, const char *query_name, const char *what, OCIError *eh) { char buffer[2048]; @@@ -93,6 -94,11 +94,11 @@@ int status; unsigned int record_number; + if (db_name == NULL) + db_name = "(none)"; + if (query_name == NULL) + query_name = "(none)"; + /* An operation may cause / return multiple errors. Loop until we have * handled all errors available (with a fail-save limit of 16). */ for (record_number = 1; record_number <= 16; record_number++) @@@ -122,12 -128,14 +128,14 @@@ buffer[buffer_length] = 0; } - ERROR ("oracle plugin: %s: %s failed: %s", where, what, buffer); + ERROR ("oracle plugin: %s (db = %s, query = %s): %s failed: %s", + where, db_name, query_name, what, buffer); } else { - ERROR ("oracle plugin: %s: %s failed. Additionally, OCIErrorGet failed with status %i.", - where, what, status); + ERROR ("oracle plugin: %s (db = %s, query = %s): %s failed. " + "Additionally, OCIErrorGet failed with status %i.", + where, db_name, query_name, what, status); return; } } @@@ -344,7 -352,7 +352,7 @@@ static int o_config (oconfig_item_t *ci oconfig_item_t *child = ci->children + i; if (strcasecmp ("Query", child->key) == 0) udb_query_create (&queries, &queries_num, child, - /* callback = */ NULL, /* legacy mode = */ 0); + /* callback = */ NULL); else if (strcasecmp ("Database", child->key) == 0) o_config_add_database (child); else @@@ -427,7 -435,8 +435,8 @@@ static int o_read_database_query (o_dat OCI_HTYPE_STMT, /* user_data_size = */ 0, /* user_data = */ NULL); if (status != OCI_SUCCESS) { - o_report_error ("o_read_database_query", "OCIHandleAlloc", oci_error); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIHandleAlloc", oci_error); oci_statement = NULL; return (-1); } @@@ -438,7 -447,8 +447,8 @@@ /* mode = */ OCI_DEFAULT); if (status != OCI_SUCCESS) { - o_report_error ("o_read_database_query", "OCIStmtPrepare", oci_error); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIStmtPrepare", oci_error); OCIHandleFree (oci_statement, OCI_HTYPE_STMT); oci_statement = NULL; return (-1); @@@ -462,10 -472,8 +472,8 @@@ /* mode = */ OCI_DEFAULT); if (status != OCI_SUCCESS) { - DEBUG ("oracle plugin: o_read_database_query: status = %i (%#x)", status, status); - o_report_error ("o_read_database_query", "OCIStmtExecute", oci_error); - ERROR ("oracle plugin: o_read_database_query: " - "Failing statement was: %s", udb_query_get_statement (q)); + o_report_error ("o_read_database_query", db->name, udb_query_get_name (q), + "OCIStmtExecute", oci_error); return (-1); } /* }}} */ @@@ -478,7 -486,8 +486,8 @@@ OCI_ATTR_PARAM_COUNT, oci_error); if (status != OCI_SUCCESS) { - o_report_error ("o_read_database_query", "OCIAttrGet", oci_error); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIAttrGet", oci_error); return (-1); } /* }}} */ @@@ -556,8 -565,10 +565,10 @@@ if (status != OCI_SUCCESS) { /* This is probably alright */ - DEBUG ("oracle plugin: o_read_database_query: status = %#x (= %i);", status, status); - o_report_error ("o_read_database_query", "OCIParamGet", oci_error); + DEBUG ("oracle plugin: o_read_database_query: status = %#x (= %i);", + status, status); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIParamGet", oci_error); status = OCI_SUCCESS; break; } @@@ -569,8 -580,8 +580,8 @@@ if (status != OCI_SUCCESS) { OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM); - o_report_error ("o_read_database_query", "OCIAttrGet (OCI_ATTR_NAME)", - oci_error); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIAttrGet (OCI_ATTR_NAME)", oci_error); continue; } @@@ -595,7 -606,8 +606,8 @@@ NULL, NULL, NULL, OCI_DEFAULT); if (status != OCI_SUCCESS) { - o_report_error ("o_read_database_query", "OCIDefineByPos", oci_error); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIDefineByPos", oci_error); continue; } } /* for (j = 1; j <= param_counter; j++) */ @@@ -603,7 -615,7 +615,7 @@@ 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): " @@@ -626,7 -638,8 +638,8 @@@ } else if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) { - o_report_error ("o_read_database_query", "OCIStmtFetch2", oci_error); + o_report_error ("o_read_database_query", db->name, + udb_query_get_name (q), "OCIStmtFetch2", oci_error); break; } @@@ -663,7 -676,8 +676,8 @@@ static int o_read_database (o_database_ OCI_ATTR_SERVER, oci_error); if (status != OCI_SUCCESS) { - o_report_error ("o_read_database", "OCIAttrGet", oci_error); + o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet", + oci_error); return (-1); } @@@ -679,7 -693,8 +693,8 @@@ OCI_ATTR_SERVER_STATUS, oci_error); if (status != OCI_SUCCESS) { - o_report_error ("o_read_database", "OCIAttrGet", oci_error); + o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet", + oci_error); return (-1); } } @@@ -702,7 -717,11 +717,11 @@@ (OraText *) db->connect_id, (ub4) strlen (db->connect_id)); if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) { - o_report_error ("o_read_database", "OCILogon", oci_error); + char errfunc[256]; + + ssnprintf (errfunc, sizeof (errfunc), "OCILogon(\"%s\")", db->connect_id); + + o_report_error ("o_read_database", db->name, NULL, errfunc, oci_error); DEBUG ("oracle plugin: OCILogon (%s): db->oci_service_context = %p;", db->connect_id, db->oci_service_context); db->oci_service_context = NULL; diff --combined src/rrdtool.c index 56a82d03,2b384d09..e5f964e5 --- a/src/rrdtool.c +++ b/src/rrdtool.c @@@ -40,11 -40,11 +40,11 @@@ */ 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 +107,10 @@@ static rrdcreate_config_t rrdcreate_con /* 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; @@@ -185,7 -185,7 +185,7 @@@ static int srrd_update (char *filename if (status != 0) { WARNING ("rrdtool plugin: rrd_update_r failed: %s: %s", - argv[1], rrd_get_error ()); + filename, rrd_get_error ()); } sfree (new_argv); @@@ -199,13 -199,11 +199,13 @@@ static int value_list_to_string (char * { 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; @@@ -305,7 -303,7 +305,7 @@@ static void *rrd_queue_thread (void __a pthread_mutex_lock (&queue_lock); /* Wait for values to arrive */ - while (true) + while (42) { struct timespec ts_wait; @@@ -344,7 -342,7 +344,7 @@@ &ts_wait); if (status == ETIMEDOUT) break; - } /* while (true) */ + } /* while (42) */ /* XXX: If you need to lock both, cache_lock and queue_lock, at * the same time, ALWAYS lock `cache_lock' first! */ @@@ -512,11 -510,10 +512,11 @@@ static int rrd_queue_dequeue (const cha 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; @@@ -525,11 -522,9 +525,11 @@@ 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); @@@ -537,9 -532,7 +537,9 @@@ { 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) { @@@ -592,11 -585,10 +592,11 @@@ 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]; @@@ -606,7 -598,7 +606,7 @@@ return (0); } - now = time (NULL); + now = cdtime (); if (datadir == NULL) snprintf (key, sizeof (key), "%s.rrd", @@@ -650,43 -642,8 +650,43 @@@ 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; @@@ -707,14 -664,14 +707,14 @@@ 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; } @@@ -722,9 -679,9 +722,9 @@@ 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); } @@@ -781,11 -738,11 +781,11 @@@ } 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! */ @@@ -797,7 -754,17 +797,7 @@@ 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 { @@@ -806,7 -773,7 +806,7 @@@ } 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); @@@ -932,8 -899,8 +932,8 @@@ static int rrd_write (const data_set_t 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); @@@ -952,7 -919,7 +952,7 @@@ static int rrd_config (const char *key { if (strcasecmp ("CacheTimeout", key) == 0) { - int tmp = atoi (value); + double tmp = atof (value); if (tmp < 0) { fprintf (stderr, "rrdtool: `CacheTimeout' must " @@@ -961,7 -928,7 +961,7 @@@ "be greater than 0.\n"); return (1); } - cache_timeout = tmp; + cache_timeout = DOUBLE_TO_CDTIME_T (tmp); } else if (strcasecmp ("CacheFlush", key) == 0) { @@@ -998,7 -965,7 +998,7 @@@ } else if (strcasecmp ("StepSize", key) == 0) { - int temp = atoi (value); + unsigned long temp = strtoul (value, NULL, 0); if (temp > 0) rrdcreate_config.stepsize = temp; } @@@ -1094,10 -1061,10 +1094,10 @@@ } 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"); @@@ -1106,7 -1073,7 +1106,7 @@@ } else { - random_timeout = tmp; + random_timeout = DOUBLE_TO_CDTIME_T (tmp); } } else @@@ -1119,7 -1086,7 +1119,7 @@@ 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); @@@ -1161,16 -1128,18 +1161,16 @@@ static int rrd_init (void return (0); init_once = 1; - if (rrdcreate_config.stepsize < 0) - rrdcreate_config.stepsize = 0; if (rrdcreate_config.heartbeat <= 0) 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."); @@@ -1185,9 -1154,10 +1185,9 @@@ 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) @@@ -1204,7 -1174,7 +1204,7 @@@ } queue_thread_running = 1; - DEBUG ("rrdtool plugin: rrd_init: datadir = %s; stepsize = %i;" + DEBUG ("rrdtool plugin: rrd_init: datadir = %s; stepsize = %lu;" " heartbeat = %i; rrarows = %i; xff = %lf;", (datadir == NULL) ? "(null)" : datadir, rrdcreate_config.stepsize, diff --combined src/snmp.c index d24ca2cd,2b0b463f..6ef3b948 --- a/src/snmp.c +++ b/src/snmp.c @@@ -69,7 -69,7 +69,7 @@@ struct host_definition_ 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,6 -159,7 +159,6 @@@ static void csnmp_host_definition_destr * +-> 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) { @@@ -301,7 -302,7 +301,7 @@@ static int csnmp_config_add_data_shift if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { - WARNING ("snmp plugin: The `Scale' config option needs exactly one number argument."); + WARNING ("snmp plugin: The `Shift' config option needs exactly one number argument."); return (-1); } @@@ -542,6 -543,22 +542,6 @@@ static int csnmp_config_add_host_collec 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; @@@ -590,7 -607,7 +590,7 @@@ 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); @@@ -634,7 -651,9 +634,7 @@@ 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, @@@ -867,10 -886,12 +867,12 @@@ static int csnmp_check_res_left_subtre vb = vb->next_variable, i++) { num_checked++; - if (snmp_oid_ncompare (data->values[i].oid, - data->values[i].oid_len, - vb->name, vb->name_length, - data->values[i].oid_len) != 0) + + if ((vb->type == SNMP_ENDOFMIBVIEW) + || (snmp_oid_ncompare (data->values[i].oid, + data->values[i].oid_len, + vb->name, vb->name_length, + data->values[i].oid_len) != 0)) num_left_subtree++; } @@@ -1527,8 -1548,8 +1529,8 @@@ static int csnmp_read_value (host_defin 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; @@@ -1538,7 -1559,9 +1540,7 @@@ 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); @@@ -1560,14 -1583,14 +1562,14 @@@ 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) diff --combined src/utils_dns.c index cfd0ccfc,2899bd41..80a2ee57 --- a/src/utils_dns.c +++ b/src/utils_dns.c @@@ -45,12 -45,6 +45,12 @@@ #if HAVE_NETINET_IN_H # include #endif +#if HAVE_NETINET_IP6_H +# include +#endif +#if HAVE_NETINET_IP_COMPAT_H +# include +#endif #if HAVE_ARPA_INET_H # include #endif @@@ -124,7 -118,7 +124,7 @@@ #if HAVE_STRUCT_UDPHDR_UH_DPORT && HAVE_STRUCT_UDPHDR_UH_SPORT # define UDP_DEST uh_dport - # define UDP_SRC uh_dport + # define UDP_SRC uh_sport #elif HAVE_STRUCT_UDPHDR_DEST && HAVE_STRUCT_UDPHDR_SOURCE # define UDP_DEST dest # define UDP_SRC source @@@ -297,18 -291,13 +297,18 @@@ rfc1035NameUnpack(const char *buf, size off_t no = 0; unsigned char c; size_t len; - assert(ns > 0); + static int loop_detect = 0; + if (loop_detect > 2) + return 4; /* compression loop */ + if (ns <= 0) + return 4; /* probably compression loop */ do { if ((*off) >= sz) break; c = *(buf + (*off)); if (c > 191) { /* blasted compression */ + int rc; unsigned short s; off_t ptr; memcpy(&s, buf + (*off), sizeof(s)); @@@ -316,23 -305,18 +316,23 @@@ (*off) += sizeof(s); /* Sanity check */ if ((*off) >= sz) - return 1; + return 1; /* message too short */ ptr = s & 0x3FFF; /* Make sure the pointer is inside this message */ if (ptr >= sz) - return 2; - return rfc1035NameUnpack(buf, sz, &ptr, name + no, ns - no); + return 2; /* bad compression ptr */ + if (ptr < DNS_MSG_HDR_SZ) + return 2; /* bad compression ptr */ + loop_detect++; + rc = rfc1035NameUnpack(buf, sz, &ptr, name + no, ns - no); + loop_detect--; + return rc; } else if (c > RFC1035_MAXLABELSZ) { /* * "(The 10 and 01 combinations are reserved for future use.)" */ + return 3; /* reserved label/compression flags */ break; - return 3; } else { (*off)++; len = (size_t) c; @@@ -340,18 -324,15 +340,18 @@@ break; if (len > (ns - 1)) len = ns - 1; - if ((*off) + len > sz) /* message is too short */ - return 4; + if ((*off) + len > sz) + return 4; /* message is too short */ + if (no + len + 1 > ns) + return 5; /* qname would overflow name buffer */ memcpy(name + no, buf + (*off), len); (*off) += len; no += len; *(name + (no++)) = '.'; } } while (c > 0); - *(name + no - 1) = '\0'; + if (no > 0) + *(name + no - 1) = '\0'; /* make sure we didn't allow someone to overflow the name buffer */ assert(no <= ns); return 0; @@@ -364,10 -345,10 +364,10 @@@ handle_dns(const char *buf, int len uint16_t us; off_t offset; char *t; - int x; + int status; /* The DNS header is 12 bytes long */ - if (len < 12) + if (len < DNS_MSG_HDR_SZ) return 0; memcpy(&us, buf + 0, 2); @@@ -398,15 -379,11 +398,15 @@@ memcpy(&us, buf + 10, 2); qh.arcount = ntohs(us); - offset = 12; + offset = DNS_MSG_HDR_SZ; memset(qh.qname, '\0', MAX_QNAME_SZ); - x = rfc1035NameUnpack(buf, len, &offset, qh.qname, MAX_QNAME_SZ); - if (0 != x) + status = rfc1035NameUnpack(buf, len, &offset, qh.qname, MAX_QNAME_SZ); + if (status != 0) + { + INFO ("utils_dns: handle_dns: rfc1035NameUnpack failed " + "with status %i.", status); return 0; + } if ('\0' == qh.qname[0]) sstrncpy (qh.qname, ".", sizeof (qh.qname)); while ((t = strchr(qh.qname, '\n'))) @@@ -447,7 -424,6 +447,7 @@@ handle_udp(const struct udphdr *udp, in return 1; } +#if HAVE_NETINET_IP6_H static int handle_ipv6 (struct ip6_hdr *ipv6, int len) { @@@ -455,7 -431,7 +455,7 @@@ unsigned int offset; int nexthdr; - struct in6_addr s_addr; + struct in6_addr c_src_addr; uint16_t payload_len; if (0 > len) @@@ -463,10 -439,10 +463,10 @@@ offset = sizeof (struct ip6_hdr); nexthdr = ipv6->ip6_nxt; - s_addr = ipv6->ip6_src; + c_src_addr = ipv6->ip6_src; payload_len = ntohs (ipv6->ip6_plen); - if (ignore_list_match (&s_addr)) + if (ignore_list_match (&c_src_addr)) return (0); /* Parse extension headers. This only handles the standard headers, as @@@ -475,7 -451,6 +475,6 @@@ || (IPPROTO_HOPOPTS == nexthdr) /* Hop-by-Hop options. */ || (IPPROTO_FRAGMENT == nexthdr) /* fragmentation header. */ || (IPPROTO_DSTOPTS == nexthdr) /* destination options. */ - || (IPPROTO_DSTOPTS == nexthdr) /* destination options. */ || (IPPROTO_AH == nexthdr) /* destination options. */ || (IPPROTO_ESP == nexthdr)) /* encapsulating security payload. */ { @@@ -517,31 -492,21 +516,31 @@@ return (1); /* Success */ } /* int handle_ipv6 */ +/* #endif HAVE_NETINET_IP6_H */ + +#else /* if !HAVE_NETINET_IP6_H */ +static int +handle_ipv6 (__attribute__((unused)) void *pkg, + __attribute__((unused)) int len) +{ + return (0); +} +#endif /* !HAVE_NETINET_IP6_H */ static int handle_ip(const struct ip *ip, int len) { char buf[PCAP_SNAPLEN]; int offset = ip->ip_hl << 2; - struct in6_addr s_addr; - struct in6_addr d_addr; + struct in6_addr c_src_addr; + struct in6_addr c_dst_addr; if (ip->ip_v == 6) - return (handle_ipv6 ((struct ip6_hdr *) ip, len)); + return (handle_ipv6 ((void *) ip, len)); - in6_addr_from_buffer (&s_addr, &ip->ip_src.s_addr, sizeof (ip->ip_src.s_addr), AF_INET); - in6_addr_from_buffer (&d_addr, &ip->ip_dst.s_addr, sizeof (ip->ip_dst.s_addr), AF_INET); - if (ignore_list_match (&s_addr)) + in6_addr_from_buffer (&c_src_addr, &ip->ip_src.s_addr, sizeof (ip->ip_src.s_addr), AF_INET); + in6_addr_from_buffer (&c_dst_addr, &ip->ip_dst.s_addr, sizeof (ip->ip_dst.s_addr), AF_INET); + if (ignore_list_match (&c_src_addr)) return (0); if (IPPROTO_UDP != ip->ip_p) return 0; @@@ -635,7 -600,7 +634,7 @@@ handle_ether(const u_char * pkt, int le return 0; memcpy(buf, pkt, len); if (ETHERTYPE_IPV6 == etype) - return (handle_ipv6 ((struct ip6_hdr *) buf, len)); + return (handle_ipv6 ((void *) buf, len)); else return handle_ip((struct ip *) buf, len); } @@@ -668,7 -633,7 +667,7 @@@ handle_linux_sll (const u_char *pkt, in return 0; if (ETHERTYPE_IPV6 == etype) - return (handle_ipv6 ((struct ip6_hdr *) pkt, len)); + return (handle_ipv6 ((void *) pkt, len)); else return handle_ip((struct ip *) pkt, len); } @@@ -679,6 -644,10 +678,6 @@@ void handle_pcap(u_char *udata, const s { int status; - DEBUG ("handle_pcap (udata = %p, hdr = %p, pkt = %p): hdr->caplen = %i\n", - (void *) udata, (void *) hdr, (void *) pkt, - hdr->caplen); - if (hdr->caplen < ETHER_HDR_LEN) return; @@@ -712,7 -681,7 +711,7 @@@ break; default: - ERROR ("handle_pcap: unsupported data link type %d\n", + ERROR ("handle_pcap: unsupported data link type %d", pcap_datalink(pcap_obj)); status = 0; break;